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
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) andlib/site.ts. - Writes:
metadataexports inapp/layout.tsxand eachpage.tsx,app/sitemap.ts,app/robots.ts,app/opengraph-image.tsx(or.png),app/icon.png, and LocalBusiness JSON-LD inapp/layout.tsx.
Steps
- 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" },
};
- Every page exports its own
metadatawith a uniquetitle(under about 60 characters) anddescription(about 150 characters) written for people, using the words customers search for (service + suburb or city). - Share image:
app/opengraph-image.tsxusingImageResponsefromnext/og(1200×630, business name and tagline on the brand colour), or drop a 1200×630app/opengraph-image.png. Addaltviaexport const alt = "...". - Icons: put
app/icon.png(square, at least 512×512) andapp/apple-icon.pnginapp/. Next.js adds the<link>tags. Remove the defaultfavicon.icoif it is still the Next.js logo. 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() }));
}
app/robots.ts: allow everything in production and point to the sitemap:{ rules: { userAgent: "*", allow: "/" }, sitemap: \${site.url}/sitemap.xml\}.- Structured data: in
app/layout.tsxrender<script type="application/ld+json">with aLocalBusiness(or a more specific type such asPlumber) object:name,url,telephone,address(PostalAddress),areaServed,openingHours. Only include facts that are also visible on the page. - Check:
npm run build && npm start, then open/sitemap.xml,/robots.txtand/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
noindexand noDisallow: /in production. Vercel already sendsX-Robots-Tag: noindexon 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.txtand 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