SEO & Metadata
The starter ships with a complete SEO surface on day one: metadata API, Open Graph images, sitemap, RSS, robots, and JSON-LD structured data.
Per-page metadata
Every route exports Next.js Metadata:
// src/app/about/page.tsx
export const metadata: Metadata = {
title: "About",
description: "One-sentence page description under 160 chars.",
alternates: { canonical: "/about" },
openGraph: {
title: "About | My Product",
description: "Same or expanded description.",
url: "/about",
type: "website",
},
};
The root src/app/layout.tsx sets a site-wide template: %s | Your Product. Individual pages supply the %s part via their title field.
SEO config
Shared SEO strings live in src/config/seo.ts:
export const SEO = {
home: { title: "...", description: "..." },
blog: { title: "...", titleTemplate: "%s | My Blog" },
docs: { title: "...", description: "..." },
terms: { title: "...", description: "..." },
privacy: { title: "...", description: "..." },
license: { title: "...", description: "..." },
};
Import into any route and spread into Metadata.
Open Graph image
src/app/opengraph-image.tsx generates a 1200×630 OG card at runtime using next/og. Edit the JSX to match your brand: colors, logo, typography all pull from your theme tokens.
Individual pages can override by adding their own opengraph-image.tsx in their route folder.
Sitemap
src/app/sitemap.ts emits /sitemap.xml. It includes:
- Static routes (home, blog, docs, legal pages)
- All blog posts from
BLOG_POSTS
Add new dynamic routes by extending the array.
robots.txt
src/app/robots.ts emits /robots.txt. The default allows all bots with a reference to the sitemap. Restrict paths via the disallow array.
RSS feed
src/app/rss.xml/route.ts emits a valid RSS 2.0 feed of blog posts. Link it from your header or footer for subscribers using feed readers.
JSON-LD structured data
src/components/seo/ provides React components that emit <script type="application/ld+json">:
<OrganizationSchema />: site-wide, injected in root layout<WebSiteSchema />: site-wide, with search action<BlogPostingSchema />: per blog post<TechArticleSchema />: per doc page<BreadcrumbListSchema />: for all internal pages
These give Google the structured data it uses for rich results (breadcrumbs, article cards, search box).
Canonical URLs
Every page should have a canonical in its alternates. This prevents duplicate-content penalties when the same page is reachable via /blog, /blog/, /blog?ref=twitter, etc.
alternates: { canonical: "/blog/your-slug" },
Verification
NEXT_PUBLIC_GSC_VERIFICATION env var automatically injects the Google Search Console verification tag when set. For other providers (Bing, Yandex), add their <meta> tags to layout.tsx.
Checklist before going live
- Unique
titleanddescriptionon every route - Canonical URLs set
-
NEXT_PUBLIC_APP_URLset to your production URL - OG image renders correctly (check
/opengraph-image) -
/sitemap.xmllists all pages you want indexed -
/robots.txtallows the routes you want crawled - Submit sitemap to Google Search Console
Next
- Deployment: ship to production