diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 836495b..ca658da 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -119,6 +119,12 @@ importers: site: dependencies: + '@takumi-rs/image-response': + specifier: ^0.62.8 + version: 0.62.8 + '@takumi-rs/wasm': + specifier: ^0.62.8 + version: 0.62.8 es-module-lexer: specifier: 1.7.0 version: 1.7.0 diff --git a/site/package.json b/site/package.json index 86f3bf5..1f67421 100644 --- a/site/package.json +++ b/site/package.json @@ -8,6 +8,8 @@ "preview": "vocs preview" }, "dependencies": { + "@takumi-rs/image-response": "^0.62.8", + "@takumi-rs/wasm": "^0.62.8", "react": "^19", "react-dom": "^19", "vocs": "latest", diff --git a/site/public/fonts/inter-regular.woff2 b/site/public/fonts/inter-regular.woff2 new file mode 100644 index 0000000..2bcd222 Binary files /dev/null and b/site/public/fonts/inter-regular.woff2 differ diff --git a/site/public/fonts/inter-semibold.woff2 b/site/public/fonts/inter-semibold.woff2 new file mode 100644 index 0000000..fbae113 Binary files /dev/null and b/site/public/fonts/inter-semibold.woff2 differ diff --git a/site/public/og-image.png b/site/public/og-image.png deleted file mode 100644 index b955d64..0000000 Binary files a/site/public/og-image.png and /dev/null differ diff --git a/site/src/pages.gen.ts b/site/src/pages.gen.ts index 22bf9f4..17b78c6 100644 --- a/site/src/pages.gen.ts +++ b/site/src/pages.gen.ts @@ -5,6 +5,7 @@ import type { PathsForPages } from 'waku/router' // prettier-ignore type Page = + | { path: '/_api/api/og'; render: 'static' } | { path: '/api/Block'; render: 'static' } | { path: '/api/Block/types'; render: 'static' } | { path: '/api/Handler/fromAbi'; render: 'static' } diff --git a/site/src/pages/_api/api/og.tsx b/site/src/pages/_api/api/og.tsx new file mode 100644 index 0000000..70acd1e --- /dev/null +++ b/site/src/pages/_api/api/og.tsx @@ -0,0 +1,99 @@ +import { ImageResponse } from '@takumi-rs/image-response/wasm' +import wasmUrl from '@takumi-rs/wasm/takumi_wasm_bg.wasm?url' + +const assets = new Map>() + +// The wasm is a Vite-emitted asset and the fonts live in `public/`; fetch +// them from our own origin at request time (the pattern vocs' built-in +// `Handler.og` uses for its wasm). +function loadAsset(path: string, origin: string) { + let asset = assets.get(path) + if (!asset) { + asset = fetch(new URL(path, origin)).then((response) => { + if (!response.ok) throw new Error(`Failed to load asset: ${path}`) + return response.arrayBuffer() + }) + assets.set(path, asset) + } + return asset +} + +export default async function handler(request: Request) { + const url = new URL(request.url) + const title = url.searchParams.get('title') || 'OpenIndex' + const description = url.searchParams.get('description') || '' + const logo = new URL('/logo-dark.png', url.origin).href + + const [wasm, interRegular, interSemiBold] = await Promise.all([ + loadAsset(wasmUrl, url.origin), + loadAsset('/fonts/inter-regular.woff2', url.origin), + loadAsset('/fonts/inter-semibold.woff2', url.origin), + ]) + + return new ImageResponse( +
+ +
+
+ {title} +
+ {description && ( +
+ {description} +
+ )} +
+
+ openindex.splits.org +
+
, + { + module: wasm, + fonts: [ + { name: 'Inter', data: interRegular, weight: 400 }, + { name: 'Inter', data: interSemiBold, weight: 600 }, + ], + width: 1200, + height: 630, + format: 'png', + headers: { + 'cache-control': 'public, max-age=3600, s-maxage=86400', + }, + }, + ) +} diff --git a/site/vocs.config.ts b/site/vocs.config.ts index 8cce45e..c5a81f9 100644 --- a/site/vocs.config.ts +++ b/site/vocs.config.ts @@ -12,8 +12,9 @@ export default defineConfig({ // Twoslash hover popups surface viem's JSDoc, which links to viem.sh-relative // paths (e.g. /docs/actions/public/introduction) that don't exist on this site. checkDeadlinks: 'warn', - description: 'Type-safe Ethereum indexer built on viem.', - ogImageUrl: '/og-image.png', + description: 'Easier indexing for Ethereum', + ogImageUrl: + 'https://openindex.splits.org/api/og?title=%title&description=%description', iconUrl: { light: '/logo-light.png', dark: '/logo-dark.png' }, logoUrl: { light: '/logo-light.png', dark: '/logo-dark.png' }, accentColor: 'light-dark(#303030, #F7F7F7)',