Adds `useSiteMeta()` composable that wraps useSeoMeta with site defaults (title template, canonical URL, og/twitter image, og:site_name) and absolute-URL handling via runtimeConfig.public.appUrl. Adds /og/events/[slug].png route that renders per-event OG images via satori + @resvg/resvg-js, cached on disk by slug + updatedAt. Bundles Brygada 1918 + Commit Mono fonts as server assets, ships a fallback default.png, and patches @shuding/opentype.js via patch-package. Converts ~25 pages from useHead to useSiteMeta and adds noindex on private/auth/admin pages.
37 lines
1.1 KiB
JavaScript
37 lines
1.1 KiB
JavaScript
import { mkdir, readFile, writeFile } from 'node:fs/promises'
|
|
import { dirname, resolve } from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
const CACHE_DIR = resolve(__dirname, '../../.cache/og')
|
|
|
|
let ensured = false
|
|
|
|
async function ensureCacheDir() {
|
|
if (ensured) return
|
|
await mkdir(CACHE_DIR, { recursive: true })
|
|
ensured = true
|
|
}
|
|
|
|
// Returns cached PNG buffer or null. Key must be safe for a filename.
|
|
export async function getCachedOG(key) {
|
|
await ensureCacheDir()
|
|
try {
|
|
return await readFile(resolve(CACHE_DIR, `${key}.png`))
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
export async function setCachedOG(key, buffer) {
|
|
await ensureCacheDir()
|
|
await writeFile(resolve(CACHE_DIR, `${key}.png`), buffer)
|
|
}
|
|
|
|
// Build a safe, deterministic cache key from event slug + updatedAt timestamp.
|
|
// Slug is already URL-safe; updatedAt busts the cache on any edit.
|
|
export function eventCacheKey(event) {
|
|
const slug = String(event.slug || event._id).replace(/[^a-zA-Z0-9_-]/g, '_')
|
|
const stamp = event.updatedAt ? new Date(event.updatedAt).getTime() : 0
|
|
return `event-${slug}-${stamp}`
|
|
}
|