mirror of
https://github.com/BradNut/personal-website-sveltekit
synced 2025-09-08 23:20:18 +00:00
Merge pull request #21 from BradNut/development
Moving og generation to lib component (Geoff Rich influenced).
This commit is contained in:
commit
86ce7024d9
5 changed files with 57 additions and 37 deletions
|
|
@ -10,12 +10,12 @@
|
|||
|
||||
<div class="social-card" style={`width: ${width}px; height: ${height}px;`}>
|
||||
<div class="social-card-header">
|
||||
<div class="social-card-title">
|
||||
<div class="social-card-image">
|
||||
<img src={image || '/images/b_shell_nut_favicon.png'} alt="Bradley Shellnut" />
|
||||
</div>
|
||||
<h1>{header}</h1>
|
||||
<div class="social-card-title">
|
||||
<div class="social-card-image">
|
||||
<img src={image || '/images/b_shell_nut_favicon.png'} alt="Bradley Shellnut" />
|
||||
</div>
|
||||
<h1>{header}</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="social-card-content">
|
||||
<h2 class="page">{page}</h2>
|
||||
|
|
|
|||
40
src/lib/renderImage.ts
Normal file
40
src/lib/renderImage.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import satori from 'satori';
|
||||
import { Resvg } from '@resvg/resvg-js';
|
||||
import { html as toReactNode } from 'satori-html';
|
||||
|
||||
// we use a Vite plugin to turn this import into the result of fs.readFileSync during build
|
||||
import firaSansSemiBold from '$lib/fonts/FiraSans-SemiBold.ttf';
|
||||
import { dev } from '$app/environment';
|
||||
|
||||
export async function componentToPng(component, props, height, width) {
|
||||
const result = component.render(props);
|
||||
const markup = toReactNode(`${result.html}<style lang="css">${result.css.code}</style>`);
|
||||
|
||||
const svg = await satori(markup, {
|
||||
fonts: [
|
||||
{
|
||||
name: 'Fira Sans',
|
||||
data: Buffer.from(firaSansSemiBold),
|
||||
style: 'normal'
|
||||
}
|
||||
],
|
||||
height: +height,
|
||||
width: +width
|
||||
});
|
||||
|
||||
const resvg = new Resvg(svg, {
|
||||
fitTo: {
|
||||
mode: 'width',
|
||||
value: +width
|
||||
}
|
||||
});
|
||||
|
||||
const png = resvg.render();
|
||||
|
||||
return new Response(png.asPng(), {
|
||||
headers: {
|
||||
'content-type': 'image/png',
|
||||
'cache-control': dev ? 'no-cache, no-store' : 'public, immutable, no-transform, max-age=86400'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { BANDCAMP_USERNAME, USE_REDIS_CACHE } from '$env/static/private';
|
||||
import scrapeIt from 'scrape-it';
|
||||
import type { ScrapeResult } from 'scrape-it';
|
||||
import { redis } from '../server/redis';
|
||||
import { redis } from '$lib/server/redis';
|
||||
import type { Album } from '../types/album';
|
||||
|
||||
export async function fetchBandcampAlbums() {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,12 @@ import type { PageServerLoad } from './$types';
|
|||
import { fetchBandcampAlbums } from '$lib/util/fetchBandcampAlbums';
|
||||
|
||||
export const load: PageServerLoad = async ({ fetch, setHeaders, url }) => {
|
||||
const baseUrl = new URL(url.origin).href || PUBLIC_SITE_URL || 'https://bradleyshellnut.com';
|
||||
let baseUrl = 'https://bradleyshellnut.com';
|
||||
if (url.origin.includes('prerender')) {
|
||||
baseUrl = PUBLIC_SITE_URL || 'https://bradleyshellnut.com';
|
||||
} else {
|
||||
baseUrl = new URL(url.origin).href || PUBLIC_SITE_URL || 'https://bradleyshellnut.com';
|
||||
}
|
||||
const currentPageUrl = new URL(url.pathname, url.origin).href;
|
||||
|
||||
const metaTags: MetaTagsProps = Object.freeze({
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import { Resvg } from '@resvg/resvg-js';
|
|||
import { html as toReactNode } from 'satori-html';
|
||||
import FiraSansSemiBold from '$lib/fonts/FiraSans-SemiBold.ttf';
|
||||
import SocialImageCard from '$lib/components/socialImageCard.svelte';
|
||||
import { dev } from '$app/environment';
|
||||
import { componentToPng } from '$root/lib/renderImage';
|
||||
|
||||
const height = 630;
|
||||
const width = 1200;
|
||||
|
|
@ -14,7 +16,8 @@ export const GET: RequestHandler = async ({ url }) => {
|
|||
const header = url.searchParams.get('header') ?? undefined;
|
||||
const page = url.searchParams.get('page') ?? undefined;
|
||||
const content = url.searchParams.get('content') ?? '';
|
||||
const result = SocialImageCard.render({
|
||||
|
||||
return componentToPng(SocialImageCard, {
|
||||
header,
|
||||
page,
|
||||
content,
|
||||
|
|
@ -22,35 +25,7 @@ export const GET: RequestHandler = async ({ url }) => {
|
|||
width,
|
||||
height,
|
||||
url: new URL(url.origin).href
|
||||
});
|
||||
console.log('result', result);
|
||||
const element = toReactNode(`${result.html}<style>${result.css.code}</style>`);
|
||||
const svg = await satori(element, {
|
||||
fonts: [
|
||||
{
|
||||
name: 'Fira Sans',
|
||||
data: Buffer.from(FiraSansSemiBold),
|
||||
style: 'normal'
|
||||
}
|
||||
],
|
||||
height,
|
||||
width
|
||||
});
|
||||
|
||||
const resvg = new Resvg(svg, {
|
||||
fitTo: {
|
||||
mode: 'width',
|
||||
value: width
|
||||
}
|
||||
});
|
||||
|
||||
const image = resvg.render();
|
||||
|
||||
return new Response(image.asPng(), {
|
||||
headers: {
|
||||
'content-type': 'image/png'
|
||||
}
|
||||
});
|
||||
}, height, width);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue