P PasteCode
Playbook

Prompt-to-PR : Ajouter un sitemap et un robots.txt

Procédure standard pour ajouter un sitemap XML dynamique et un robots.txt à un projet Next.js ou Astro — format lastmod correct, priorité et règles d'exploration pour le SEO en production.

CursorClaude CodeCodexWindsurf Next.jsAstroTypeScript
.md .json Difficulté: Facile Mis à jour 8 juin 2026

Les sitemaps et robots.txt sont les premières primitives SEO qu’un agent manipule, et elles sont souvent erronées — mauvais format lastmod, directive Sitemap: manquante dans robots, ou pages bloquées incluses par inadvertance. Ce guide les corrige.

1. Exigence

Produire un sitemap XML couvrant toutes les routes publiques (contenu statique + dynamique depuis la base de données) et un robots.txt qui bloque les chemins admin/API et référence le sitemap. Fonctionne à la fois avec Next.js App Router et Astro ; choisissez l’approche correcte pour votre framework.

2. Premier prompt

First Prompt
Add a sitemap.xml and robots.txt to this project. Use the correct approach
for the framework detected below.
### If Next.js 14+:
1. Create `src/app/sitemap.ts` using the Next.js `MetadataRoute.Sitemap`
return type. Include:
- All static routes: /, /pricing, /blog, /about (hardcoded is fine).
- All dynamic blog posts: fetch slugs from the DB using the existing
query helper, return lastModified from the post's updatedAt field.
- Use `process.env.NEXT_PUBLIC_APP_URL` as the base URL.
- Correct W3C datetime format for lastModified (ISO 8601).
2. Create `src/app/robots.ts` using MetadataRoute.Robots.
- Allow: all routes.
- Disallow: /admin, /api, /dashboard.
- Add `sitemap: process.env.NEXT_PUBLIC_APP_URL + "/sitemap.xml"`.
### If Astro:
1. Add `@astrojs/sitemap` integration. In astro.config.ts, add
`sitemap({ filter: (page) => !page.includes("/admin") })` and set
`site: process.env.SITE_URL`.
2. Create `public/robots.txt`:
User-agent: *
Disallow: /admin
Disallow: /api
Sitemap: <SITE_URL>/sitemap-index.xml
Do not create a custom sitemap endpoint if the integration handles it.
Do not block / or any public content pages.

3. Modifications de fichiers attendues

### Next.js
src/app/sitemap.ts (new — dynamic MetadataRoute.Sitemap)
src/app/robots.ts (new — MetadataRoute.Robots)
### Astro
astro.config.ts (add sitemap integration + filter)
public/robots.txt (new)
.env.example (SITE_URL added if missing)

4. Liste de vérification

  • L’URL de base provient d’une variable d’environnement — pas codée en dur comme http://localhost:3000.
  • lastModified est un objet JavaScript Date (Next.js le convertit en ISO 8601) ou déjà une chaîne ISO valide — pas "undefined" ou absent.
  • /admin, /api et /dashboard sont dans la liste Disallow.
  • La directive Sitemap: dans robots.txt utilise une URL absolue.
  • Les routes dynamiques (articles de blog) sont incluses via une requête DB, pas seulement les routes statiques.
  • Le sitemap n’inclut pas les pages 404, de redirection ou noindex.
  • bun run build puis curl /sitemap.xml retourne un XML valide (vérifier avec xmllint).

5. Commandes de test

Terminal window
bun run build && bun run start
# or for Astro:
bun run build && bun run preview
# Validate sitemap XML
curl -s http://localhost:3000/sitemap.xml | xmllint --format - | head -40
# Confirm robots.txt
curl http://localhost:3000/robots.txt
# Confirm admin is disallowed and sitemap directive is present
grep -E "Disallow|Sitemap" <(curl -s http://localhost:3000/robots.txt)
# Google Rich Results / URL Inspection simulation
curl -A "Googlebot" http://localhost:3000/sitemap.xml -I

6. Échecs courants

  • lastModified est "undefined" — le champ updatedAt du post est nul. Sécurisation : lastModified: post.updatedAt ?? post.createdAt ?? new Date().
  • Le sitemap retourne 404src/app/sitemap.ts est manquant ou placé en dehors du répertoire app.
  • Toutes les routes interdites — l’agent ajoute Disallow: / par erreur. Confirmez que seuls les chemins admin/API sont bloqués.
  • La directive Sitemap: a une URL relative — Google l’ignore. Doit être absolue : https://example.com/sitemap.xml.
  • Sitemap statique uniquement — l’agent code en dur les slugs de blog au lieu d’interroger la DB. Confirmez que la fonction sitemap est async et récupère des données réelles.

7. Prompt de correction

Fix Prompt
The sitemap.xml at /sitemap.xml includes every blog post with
lastModified "undefined" (rendered as the string).
Fix in src/app/sitemap.ts:
const posts = await getBlogPosts();
return posts.map((post) => ({
url: `${BASE_URL}/blog/${post.slug}`,
lastModified: post.updatedAt ?? post.createdAt ?? new Date(),
changeFrequency: "weekly",
priority: 0.8,
}));
Ensure getBlogPosts() returns rows that include updatedAt and createdAt.

8. Description de la PR

PR description
## SEO: Add dynamic sitemap.xml and robots.txt
**Next.js**: `src/app/sitemap.ts` + `src/app/robots.ts` using built-in
`MetadataRoute` types. Sitemap includes static routes + all published blog
posts with correct `lastModified` timestamps from the DB.
**robots.txt** disallows `/admin`, `/api`, `/dashboard`; includes absolute
`Sitemap:` directive pointing to the generated `/sitemap.xml`.
Base URL read from `NEXT_PUBLIC_APP_URL` — no localhost URLs in production.