StartupKitstartupkit
SEO

Page Metadata

How to generate SEO metadata for your pages

Generate complete SEO metadata for your pages with a single function call.

Basic Usage

Individual Pages

app/pricing/page.tsx
import {  } from "@startupkit/seo"

export const  = ({
  : "Pricing",
  : "Simple, transparent pricing for teams of all sizes",
  : "/pricing",
  : "https://myapp.com",
  : "My App"
})

export default function () {
  return <>Pricing content</>
}

Root Layout

For root layouts, include titleTemplate to create consistent page titles:

app/layout.tsx
import {  } from "@startupkit/seo"

export const  = ({
  : "My App",
  : "The best app for doing things",
  : "https://myapp.com",
  : "My App",
  : "%s | My App",
  : "@myapp"
})

With titleTemplate: "%s | My App":

  • Homepage shows: "My App"
  • Pricing page shows: "Pricing | My App"

Parameters

Common Parameters

ParameterTypeRequiredDescription
titlestringYesPage title
descriptionstringYesMeta description
baseUrlstringYesFull base URL (e.g., https://myapp.com)
siteNamestringYesSite name for OpenGraph
ogImagestringNoOpenGraph image URL (default: /hero/og.avif)
twitterHandlestringNoTwitter username (e.g., @myapp)

Page-Specific Parameters

ParameterTypeDescription
pathstringPage path (e.g., /about) for canonical URL
noIndexbooleanAdd noindex directive (exclude from search)

Root Layout Parameters

ParameterTypeDescription
titleTemplatestringTitle template (e.g., %s | Site Name)
keywordsstring[]SEO keywords
iconsobjectFavicon configuration
manifeststringWeb manifest path

What Gets Generated

For Individual Pages

({
  : "About Us",
  : "Learn about our company",
  : "/about",
  : "https://myapp.com",
  : "My App",
  : "/og/about.png",
  : "@myapp"
})

Generates:

const  = {
  : "About Us",
  : "Learn about our company",
  : new ("https://myapp.com"),
  : {
    : "website",
    : "en_US",
    : "https://myapp.com/about",
    : "My App",
    : "About Us",
    : "Learn about our company",
    : [{
      : "/og/about.png",
      : 1200,
      : 630,
      : "About Us"
    }]
  },
  : {
    : "summary_large_image",
    : "About Us",
    : "Learn about our company",
    : ["/og/about.png"],
    : "@myapp"
  },
  : {
    : "https://myapp.com/about"
  }
}

Dynamic Metadata

For dynamic pages, use generateMetadata as a function:

app/blog/[slug]/page.tsx
import {  as  } from "@startupkit/seo"

interface Props {
  : <{ : string }>
}

export async function ({  }: Props) {
  const {  } = await 
  const  = await getPost()

  return ({
    : .title,
    : .excerpt,
    : `/blog/${}`,
    : "https://myapp.com",
    : "My App",
    : .coverImage
  })
}

OpenGraph Images

Default Image

The default OG image path is /hero/og.avif. Override per-page:

({
  : "Features",
  : "Explore our features",
  : "/og/features.png",  // Custom OG image
  // ...
})
  • Width: 1200px
  • Height: 630px
  • Format: PNG, JPEG, or AVIF

Dynamic OG Images

Generate OG images with Next.js:

app/og/[...slug]/route.tsx
import {  } from "next/og"

export async function (: Request) {
  const {  } = new (.)
  const  = .("title") ?? "My App"

  return new (
    (
      < ={{ : "flex", : 48 }}>
        {}
      </>
    ),
    { : 1200, : 630 }
  )
}

Then use:

({
  : `/og?title=${(.)}`,
  // ...
})

noIndex Pages

Exclude pages from search engines:

app/dashboard/page.tsx
export const  = ({
  : "Dashboard",
  : "Your personal dashboard",
  : "/dashboard",
  : "https://myapp.com",
  : "My App",
  : true  // Adds noindex, nofollow
})

Common noIndex pages:

  • Dashboard/app pages
  • User settings
  • Checkout flows
  • Internal tools

Canonical URLs

Canonical URLs prevent duplicate content issues:

({
  : "/about",  // Generates canonical: https://myapp.com/about
  // ...
})

For pages with query parameters:

// /products?category=shoes should canonicalize to /products
({
  : "/products",  // Not /products?category=shoes
  // ...
})

Centralized Configuration

Create a helper for consistent configuration:

lib/seo.ts
import {  as  } from "@startupkit/seo"

const  = {
  : "https://myapp.com",
  : "My App",
  : "@myapp",
  : "/og/default.png"
}

export function (: {
  : string
  : string
  ?: string
  ?: string
  ?: boolean
}) {
  return ({
    ...,
    ...
  })
}

Use in pages:

app/features/page.tsx
import {  } from "@/lib/seo"

export const  = ({
  : "Features",
  : "Explore our powerful features",
  : "/features"
})

Next Steps

On this page