Svelte
Render Svelte components to images via svelte/server.
For a plain Svelte project (no SvelteKit), render the component to HTML with svelte/server and hand the string to ImageResponse. Same renderer, no SvelteKit-specific glue. If you're on SvelteKit, see the SvelteKit guide — it builds on the same svelte/server API but inside a +server.ts.
+server.ts
app.css
Install
See Installation for the package commands. You need takumi-js plus the Tailwind toolchain if your component uses utility classes.
Write the component
css="injected" ships the <style> block inline with the HTML — Takumi reads CSS from the markup, not from imports the browser would resolve.
<script lang="ts">
const { name = "Goo goo gaga" } = $props();
</script>
<svelte:options css="injected" />
<div
id="og-image"
class="text-7xl font-semibold text-black w-full h-full flex items-center justify-center p-12 flex-col gap-4"
>
<div class="text-center whitespace-pre-wrap leading-normal">
Welcome {name} to
<span class="text-svelte font-bold">Svelte</span> world
</div>
</div>
<style>
#og-image {
background-image: linear-gradient(to bottom right, var(--color-orange-50), var(--color-red-200));
}
</style>Render in the handler
import { render } from "svelte/server";
import style from "../app.css?inline";
import ImageResponse from "takumi-js/response";
import OgImage from "$lib/components/OgImage.svelte";
export async function GET({ url }) {
const { body, head } = await render(OgImage, {
props: { name: url.searchParams.get("name") ?? "Goo goo gaga" },
});
return new ImageResponse(`${head}${body}`, {
width: 1200,
height: 630,
stylesheets: [style],
fonts: [
{
name: "Geist",
data: () =>
fetch("https://takumi.kane.tw/fonts/Geist.woff2").then((res) => res.arrayBuffer()),
},
],
});
}Edit on GitHub
Last updated on