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 title and description on every route
  • Canonical URLs set
  • NEXT_PUBLIC_APP_URL set to your production URL
  • OG image renders correctly (check /opengraph-image)
  • /sitemap.xml lists all pages you want indexed
  • /robots.txt allows the routes you want crawled
  • Submit sitemap to Google Search Console

Next