- Add sitemap.ts and robots.ts - pageMetadata() helper: consistent title, canonical URL, Open Graph, Twitter card and feed alternate on every page - Generated OG images: a site card, and per post either the cover image or a branded title card (pre-rendered at build) - BlogPosting JSON-LD on post pages - Fail fast with a clear error when SITE_URL is missing Content loading: - Validate post frontmatter at build time and normalize dates to ISO (fixes invalid <time datetime> values) - Add draft: true support (drafts only render in development) - Cache markdown rendering so metadata and page share one render - Replace the three copy-pasted about/projects/setup pages with a shared MarkdownPage component
19 lines
723 B
TypeScript
19 lines
723 B
TypeScript
import { getAllPostSlugs, getPostMeta } from '@/lib/posts'
|
|
import { ogImageSize, renderOgCard, renderOgCover } from '@/lib/og-image'
|
|
|
|
export const size = ogImageSize
|
|
export const contentType = 'image/png'
|
|
|
|
export function generateStaticParams() {
|
|
return getAllPostSlugs().map((slug) => ({ slug }))
|
|
}
|
|
|
|
/** Uses the post's cover image when it has one, otherwise a generated title card. */
|
|
export default async function OpengraphImage({ params }: { params: Promise<{ slug: string }> }) {
|
|
const { slug } = await params
|
|
const meta = getPostMeta(slug)
|
|
return (
|
|
(meta.coverImage && renderOgCover(meta.coverImage)) ??
|
|
renderOgCard({ title: meta.title, description: meta.description, eyebrow: meta.category })
|
|
)
|
|
}
|