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.
29 lines
902 B
JavaScript
29 lines
902 B
JavaScript
// GET /og/events/[slug].png — generated Open Graph image for an event.
|
|
// Cached on disk by slug + event.updatedAt so any admin edit busts the cache.
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const slug = getRouterParam(event, 'slug')
|
|
if (!slug) {
|
|
throw createError({ statusCode: 400, statusMessage: 'Missing slug' })
|
|
}
|
|
|
|
// .png suffix is part of the route filename, but slugs in DB don't include it.
|
|
const cleanSlug = slug.replace(/\.png$/, '')
|
|
|
|
const eventDoc = await loadPublicEvent(event, cleanSlug, { lean: true })
|
|
const key = eventCacheKey(eventDoc)
|
|
|
|
let png = await getCachedOG(key)
|
|
if (!png) {
|
|
png = await renderEventOG(eventDoc)
|
|
await setCachedOG(key, png)
|
|
}
|
|
|
|
setHeader(event, 'Content-Type', 'image/png')
|
|
setHeader(
|
|
event,
|
|
'Cache-Control',
|
|
'public, max-age=3600, s-maxage=86400, stale-while-revalidate=86400'
|
|
)
|
|
return png
|
|
})
|