feat(web): full SEO stack — metadata, JSON-LD, sitemap, robots, OG image
Ported and adapted from the BuildMyDiscord SEO setup:
- lib/seo.ts — single source for site constants, the FAQ data (shared by
the rendered FAQ and the FAQPage schema so they never drift) and JSON-LD
builders.
- Rich root metadata: title template, keywords, Open Graph, Twitter card,
robots directives, canonical.
- JSON-LD: Organization + WebSite + SoftwareApplication sitewide, FAQPage
on the landing page. No AggregateRating — there are no real reviews yet.
- app/robots.ts — allow all, explicit allow-list for AI answer-engine
crawlers (GPTBot, ClaudeBot, PerplexityBot, …), disallow private routes.
- app/sitemap.ts — every public marketing + docs route.
- app/opengraph-image.tsx — monochrome on-brand 1200x630 share card.
- app/manifest.ts + public/llms.txt.
- Per-page metadata for pricing, changelog, security, privacy, terms,
docs, templates and status.
- opengraph-image + apple-icon pinned to the edge runtime — next/og
crashes during a Node-runtime prerender.
Verified: next build passes; /robots.txt, /sitemap.xml,
/manifest.webmanifest and /opengraph-image all generate.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 19:16:40 +02:00
|
|
|
import { JsonLd } from '@/components/json-ld';
|
|
|
|
|
import {
|
|
|
|
|
SEO_KEYWORDS,
|
|
|
|
|
SITE_DESCRIPTION,
|
|
|
|
|
SITE_NAME,
|
|
|
|
|
SITE_TAGLINE,
|
|
|
|
|
SITE_URL,
|
|
|
|
|
siteJsonLd,
|
|
|
|
|
} from '@/lib/seo';
|
2026-05-21 18:57:49 +02:00
|
|
|
import { GeistMono } from 'geist/font/mono';
|
|
|
|
|
import { GeistSans } from 'geist/font/sans';
|
|
|
|
|
import type { Metadata } from 'next';
|
2026-05-19 00:30:20 +02:00
|
|
|
import './globals.css';
|
|
|
|
|
|
feat(web): full SEO stack — metadata, JSON-LD, sitemap, robots, OG image
Ported and adapted from the BuildMyDiscord SEO setup:
- lib/seo.ts — single source for site constants, the FAQ data (shared by
the rendered FAQ and the FAQPage schema so they never drift) and JSON-LD
builders.
- Rich root metadata: title template, keywords, Open Graph, Twitter card,
robots directives, canonical.
- JSON-LD: Organization + WebSite + SoftwareApplication sitewide, FAQPage
on the landing page. No AggregateRating — there are no real reviews yet.
- app/robots.ts — allow all, explicit allow-list for AI answer-engine
crawlers (GPTBot, ClaudeBot, PerplexityBot, …), disallow private routes.
- app/sitemap.ts — every public marketing + docs route.
- app/opengraph-image.tsx — monochrome on-brand 1200x630 share card.
- app/manifest.ts + public/llms.txt.
- Per-page metadata for pricing, changelog, security, privacy, terms,
docs, templates and status.
- opengraph-image + apple-icon pinned to the edge runtime — next/og
crashes during a Node-runtime prerender.
Verified: next build passes; /robots.txt, /sitemap.xml,
/manifest.webmanifest and /opengraph-image all generate.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 19:16:40 +02:00
|
|
|
const TITLE = `${SITE_NAME} — ${SITE_TAGLINE}`;
|
|
|
|
|
|
2026-05-19 00:30:20 +02:00
|
|
|
export const metadata: Metadata = {
|
feat(web): full SEO stack — metadata, JSON-LD, sitemap, robots, OG image
Ported and adapted from the BuildMyDiscord SEO setup:
- lib/seo.ts — single source for site constants, the FAQ data (shared by
the rendered FAQ and the FAQPage schema so they never drift) and JSON-LD
builders.
- Rich root metadata: title template, keywords, Open Graph, Twitter card,
robots directives, canonical.
- JSON-LD: Organization + WebSite + SoftwareApplication sitewide, FAQPage
on the landing page. No AggregateRating — there are no real reviews yet.
- app/robots.ts — allow all, explicit allow-list for AI answer-engine
crawlers (GPTBot, ClaudeBot, PerplexityBot, …), disallow private routes.
- app/sitemap.ts — every public marketing + docs route.
- app/opengraph-image.tsx — monochrome on-brand 1200x630 share card.
- app/manifest.ts + public/llms.txt.
- Per-page metadata for pricing, changelog, security, privacy, terms,
docs, templates and status.
- opengraph-image + apple-icon pinned to the edge runtime — next/og
crashes during a Node-runtime prerender.
Verified: next build passes; /robots.txt, /sitemap.xml,
/manifest.webmanifest and /opengraph-image all generate.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 19:16:40 +02:00
|
|
|
metadataBase: new URL(SITE_URL),
|
|
|
|
|
title: {
|
|
|
|
|
default: TITLE,
|
|
|
|
|
template: `%s | ${SITE_NAME}`,
|
|
|
|
|
},
|
|
|
|
|
description: SITE_DESCRIPTION,
|
|
|
|
|
applicationName: SITE_NAME,
|
|
|
|
|
keywords: SEO_KEYWORDS,
|
|
|
|
|
authors: [{ name: SITE_NAME }],
|
|
|
|
|
creator: SITE_NAME,
|
|
|
|
|
publisher: SITE_NAME,
|
|
|
|
|
alternates: { canonical: '/' },
|
|
|
|
|
openGraph: {
|
|
|
|
|
type: 'website',
|
|
|
|
|
locale: 'en_US',
|
|
|
|
|
url: SITE_URL,
|
|
|
|
|
siteName: SITE_NAME,
|
|
|
|
|
title: TITLE,
|
|
|
|
|
description: SITE_DESCRIPTION,
|
|
|
|
|
},
|
|
|
|
|
twitter: {
|
|
|
|
|
card: 'summary_large_image',
|
|
|
|
|
title: TITLE,
|
|
|
|
|
description: SITE_DESCRIPTION,
|
|
|
|
|
},
|
|
|
|
|
robots: {
|
|
|
|
|
index: true,
|
|
|
|
|
follow: true,
|
|
|
|
|
googleBot: {
|
|
|
|
|
index: true,
|
|
|
|
|
follow: true,
|
|
|
|
|
'max-image-preview': 'large',
|
|
|
|
|
'max-snippet': -1,
|
|
|
|
|
'max-video-preview': -1,
|
|
|
|
|
},
|
|
|
|
|
},
|
2026-05-19 00:30:20 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
|
|
|
return (
|
2026-05-21 18:57:49 +02:00
|
|
|
<html
|
|
|
|
|
lang="en"
|
|
|
|
|
className={`${GeistSans.variable} ${GeistMono.variable}`}
|
|
|
|
|
suppressHydrationWarning
|
|
|
|
|
>
|
2026-05-21 18:57:16 +02:00
|
|
|
<body>
|
feat(web): full SEO stack — metadata, JSON-LD, sitemap, robots, OG image
Ported and adapted from the BuildMyDiscord SEO setup:
- lib/seo.ts — single source for site constants, the FAQ data (shared by
the rendered FAQ and the FAQPage schema so they never drift) and JSON-LD
builders.
- Rich root metadata: title template, keywords, Open Graph, Twitter card,
robots directives, canonical.
- JSON-LD: Organization + WebSite + SoftwareApplication sitewide, FAQPage
on the landing page. No AggregateRating — there are no real reviews yet.
- app/robots.ts — allow all, explicit allow-list for AI answer-engine
crawlers (GPTBot, ClaudeBot, PerplexityBot, …), disallow private routes.
- app/sitemap.ts — every public marketing + docs route.
- app/opengraph-image.tsx — monochrome on-brand 1200x630 share card.
- app/manifest.ts + public/llms.txt.
- Per-page metadata for pricing, changelog, security, privacy, terms,
docs, templates and status.
- opengraph-image + apple-icon pinned to the edge runtime — next/og
crashes during a Node-runtime prerender.
Verified: next build passes; /robots.txt, /sitemap.xml,
/manifest.webmanifest and /opengraph-image all generate.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 19:16:40 +02:00
|
|
|
<JsonLd data={siteJsonLd()} />
|
2026-05-21 18:57:16 +02:00
|
|
|
{children}
|
|
|
|
|
</body>
|
2026-05-19 00:30:20 +02:00
|
|
|
</html>
|
|
|
|
|
);
|
|
|
|
|
}
|