Files
andwati.com/src/components/JsonLd.tsx
T
andwati ec6401ac38 Replace Astro/Strapi site with Next.js static export
- Fresh structure: Next.js App Router + Tailwind v4 at the repo root, exported
  as static files (output: export) and served by static-web-server
- Remove the Strapi CMS, Astro app, Pagefind search, comments, old scripts,
  Lighthouse config and compose files; content in content/ is now plain
  markdown with YAML frontmatter
- Pages: About, Writing, Reading (3D bookshelf) and Portfolio, styled after
  adammaj.com
- SEO: metadata and canonicals, JSON-LD, generated OG images, sitemap, robots,
  RSS and JSON feeds, llms.txt
- Umami via PUBLIC_UMAMI_SCRIPT_URL / PUBLIC_UMAMI_WEBSITE_ID (build args)
- Dockerfile builds the export and serves it with sws.toml (security headers,
  clean URLs, .well-known, OG image content type, immutable asset caching)
- Prettier and cspell for content with a husky/lint-staged pre-commit hook
- Old redirect list dropped to start from a clean slate
2026-09-30 12:48:14 +03:00

30 lines
777 B
TypeScript

/** Renders a JSON-LD block. `<` is escaped so content can't close the script tag. */
export function JsonLd({
data,
}: {
data: Record<string, unknown> | Record<string, unknown>[];
}) {
return (
<script
type="application/ld+json"
// biome-ignore lint/security/noDangerouslySetInnerHtml: JSON-LD must be inlined; `<` is escaped
dangerouslySetInnerHTML={{
__html: JSON.stringify(data).replace(/</g, "\\u003c"),
}}
/>
);
}
export function breadcrumbs(items: { name: string; url: string }[]) {
return {
"@context": "https://schema.org",
"@type": "BreadcrumbList",
itemListElement: items.map((item, i) => ({
"@type": "ListItem",
position: i + 1,
name: item.name,
item: item.url,
})),
};
}