Frontend · How to use a skill

add-seo-metadata-and-sitemap

Adds search basics to a Next.js site, with a title and description per page, Open Graph share images, sitemap.ts, robots.ts, LocalBusiness structured data and a favicon. Use when the user wants to show up on Google, improve SEO, fix link previews, or add a sitemap or meta tags.

Version 1.1 · Updated 2026-10-31

View raw SKILL.md

Install in Claude Code, Cursor or Codex (optional)

Only for AI coding tools that read skill folders. Run one line in a terminal, in your project folder. It downloads this skill's text files from TheSkillVault and nothing else; you can read them first with “View raw SKILL.md”.

Claude Code (all your projects)

curl -fsSL --create-dirs 'https://theskillvault.ai/api/skills/add-seo-metadata-and-sitemap/raw' -o ~/'.claude/skills/add-seo-metadata-and-sitemap/SKILL.md'

Cursor (this project)

curl -fsSL --create-dirs 'https://theskillvault.ai/api/skills/add-seo-metadata-and-sitemap/raw' -o '.cursor/skills/add-seo-metadata-and-sitemap/SKILL.md'

Codex and other Agent Skills tools (this project)

curl -fsSL --create-dirs 'https://theskillvault.ai/api/skills/add-seo-metadata-and-sitemap/raw' -o '.agents/skills/add-seo-metadata-and-sitemap/SKILL.md'

Or connect the whole library over MCP

Add TheSkillVault to Cursor or add this to your app's MCP settings (read-only; help):

{
  "mcpServers": {
    "theskillvault": {
      "url": "https://theskillvault.ai/mcp"
    }
  }
}

Add SEO metadata and a sitemap

This skill adds the basic tags and files search engines and chat apps read. To find what is wrong on a live site, use audit-site-seo first.

When to use

  • A Next.js App Router site is built and needs to be findable and share nicely on social media and chat apps.
  • Link previews show no image or the wrong title.
  • Google Search Console asks for a sitemap.
  • An SEO audit found missing titles, descriptions, a sitemap or structured data.

Handoff

  • Reads: docs/website-brief.md (page list, business details) and lib/site.ts.
  • Writes: metadata exports in app/layout.tsx and each page.tsx, app/sitemap.ts, app/robots.ts, app/opengraph-image.tsx (or .png), app/icon.png, and LocalBusiness JSON-LD in app/layout.tsx.

Steps

  1. Site-wide defaults in app/layout.tsx:
   export const metadata: Metadata = {
     metadataBase: new URL(site.url),            // e.g. https://www.example.com.au
     title: { default: site.name, template: `%s | ${site.name}` },
     description: "One sentence saying what you do and where.",
     openGraph: { type: "website", siteName: site.name, locale: "en_AU" },
   };
  1. Every page exports its own metadata with a unique title (under about 60 characters) and description (about 150 characters) written for people, using the words customers search for (service + suburb or city).
  2. Share image: app/opengraph-image.tsx using ImageResponse from next/og (1200×630, business name and tagline on the brand colour), or drop a 1200×630 app/opengraph-image.png. Add alt via export const alt = "...".
  3. Icons: put app/icon.png (square, at least 512×512) and app/apple-icon.png in app/. Next.js adds the <link> tags. Remove the default favicon.ico if it is still the Next.js logo.
  4. app/sitemap.ts:
   import type { MetadataRoute } from "next";
   export default function sitemap(): MetadataRoute.Sitemap {
     return ["", "/about", "/services", "/contact", "/privacy"].map((p) => ({ url: `${site.url}${p}`, lastModified: new Date() }));
   }
  1. app/robots.ts: allow everything in production and point to the sitemap: { rules: { userAgent: "*", allow: "/" }, sitemap: \${site.url}/sitemap.xml\ }.
  2. Structured data: in app/layout.tsx render <script type="application/ld+json"> with a LocalBusiness (or a more specific type such as Plumber) object: name, url, telephone, address (PostalAddress), areaServed, openingHours. Only include facts that are also visible on the page.
  3. Check: npm run build && npm start, then open /sitemap.xml, /robots.txt and /opengraph-image. Paste a page into Google's Rich Results Test, and preview a link in a chat app after deploying.

Gotchas

  • Set metadataBase, or Open Graph image URLs come out relative and previews break.
  • Don't block the live site: no noindex and no Disallow: / in production. Vercel already sends X-Robots-Tag: noindex on preview deployments (not on a custom domain assigned to a branch).
  • One <h1> per page that matches what the page is about; titles and headings beat keyword stuffing.
  • Use a single canonical host (www or not) and redirect the other one; this is set up in the launch step.
  • Structured data that claims things not on the page (fake reviews, wrong hours) can get it ignored.

Safety

  • Keep the Search Console verification token and any analytics keys in environment variables, not in public code you share.
  • Structured data is public. Do not put private details (a home address, a personal phone) in it that are not already on the page.

Works with other stacks

On Astro, Nuxt, SvelteKit or WordPress the same pieces apply: per-page titles, a sitemap, robots rules, a share image and JSON-LD. Only the file names change. With WordPress, a plugin such as Yoast or an equivalent does most of it.

Done when

  • Every page has a unique title and description.
  • /sitemap.xml, /robots.txt and the share image load on the live site.
  • The Rich Results Test shows valid structured data, and a shared link shows the right preview.

Credits

Topic coverage informed by addyosmani/web-quality-skills (https://github.com/addyosmani/web-quality-skills, MIT © 2026 Addy Osmani). The text here is our own.

Example prompt

"Get my site showing up on Google: add page titles, a sitemap, and make the link preview show our logo when I share it."

Licence: CC BY 4.0. Attribution when you reuse it: From TheSkillVault, https://theskillvault.ai, CC BY 4.0