Fixing up the og image generation.

This commit is contained in:
Bradley Shellnut 2023-09-13 22:52:34 -07:00
parent 9f69946504
commit eac61fffe3
3 changed files with 97 additions and 37 deletions

View file

@ -1,14 +1,65 @@
<script lang="ts">
import * as Card from "$lib/components/ui/card";
export let title: string;
export let image: string;
export let description: string;
</script>
<Card.Root class="w-[350px]">
<Card.Header>
<Card.Title class="flex place-items-center gap-1"><div class="w-8 h-8"><img src="/images/bored-game.png" alt="Bored Game" /></div>{title}</Card.Title>
</Card.Header>
<Card.Content>
<slot />
</Card.Content>
</Card.Root>
<div class="social-card">
<div class="social-card-header">
<div class="social-card-title">
<div class="social-card-image">
<img src={image || '/images/bored-game.png'} alt="Bored Game" />
</div>
<p>{title}</p>
</div>
</div>
<div class="social-card-content">
<p>{description}</p>
</div>
</div>
<style>
@font-face {
font-family: 'Noto Sans';
src: url('/src/lib/NotoSans-Regular.ttf');
}
.social-card {
display: flex;
flex-direction: column;
border-radius: 0.5rem;
border-width: 1px;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
width: 350px;
}
.social-card-header {
display: flex;
padding: 1.5rem;
margin-top: 0.375rem;
flex-direction: column;
}
.social-card-title {
display: flex;
gap: 0.25rem;
place-items: center;
font-size: 1.125rem;
line-height: 1.75rem;
font-weight: 600;
letter-spacing: -0.025em;
line-height: 1;
}
.social-card-image {
display: flex;
width: 2rem;
height: 2rem;
}
.social-card-content {
display: flex;
padding: 1.5rem;
padding-top: 0;
}
</style>

View file

@ -14,7 +14,9 @@ export const load = async ({ fetch, url }) => {
description: 'Bored Game, keep track of your games',
images: [
{
url: `${new URL(url.pathname, url.origin).href}og?title=Home | Bored Game`,
url: `${
new URL(url.pathname, url.origin).href
}og?title=Home | Bored Game&description=Bored Game, keep track of your games`,
width: 1200,
height: 630
}

View file

@ -9,33 +9,40 @@ const height = 630;
const width = 1200;
export const GET: RequestHandler = async ({ url }) => {
const title = url.searchParams.get('title') ?? undefined;
const result = SocialImageCard.render({ title });
const element = toReactNode(`${result.html}<style>${result.css.code}</style>`);
const svg = await satori(element, {
fonts: [
{
name: 'Noto Sans',
data: Buffer.from(NotoSans),
style: 'normal'
try {
const ogImage = `${new URL(url.origin).href}images/bored-game.png`;
const title = url.searchParams.get('title') ?? undefined;
const description = url.searchParams.get('description') ?? '';
const result = SocialImageCard.render({ title, image: ogImage, description });
console.log('result', result);
const element = toReactNode(`${result.html}<style>${result.css.code}</style>`);
const svg = await satori(element, {
fonts: [
{
name: 'Noto Sans',
data: Buffer.from(NotoSans),
style: 'normal'
}
],
height,
width
});
const resvg = new Resvg(svg, {
fitTo: {
mode: 'width',
value: width
}
],
height,
width
});
});
const resvg = new Resvg(svg, {
fitTo: {
mode: 'width',
value: width
}
});
const image = resvg.render();
const image = resvg.render();
return new Response(image.asPng(), {
headers: {
'content-type': 'image/png'
}
});
return new Response(image.asPng(), {
headers: {
'content-type': 'image/png'
}
});
} catch (e) {
console.error(e);
}
};