Keep a sitemap current when publishing new articles

A newly published article opens correctly and appears on the blog index, but it is absent from the sitemap. The sitemap was generated from a static list during an earlier build. Another article has been withdrawn yet remains listed. Updating the page renderer cannot repair this discovery mismatch because the sitemap has a separate data path and freshness policy.
This example assumes Next.js 15 App Router, including a project on 15.1.11. The app/sitemap.ts convention can return structured sitemap entries. Its runtime and caching behavior still need to fit the application. The file's existence does not prove that new database records become visible after publication.
Establish the inclusion rule
List the resources that belong in public discovery. For this blog, include published articles with stable canonical slugs and public access. Exclude drafts, deleted records, preview routes, and administrative pages. If scheduled content exists, include it only when the publication rule considers it public. Use the same predicate as the article route rather than a second approximation.
Define whether archived public articles remain discoverable. Archiving is a product concept, not automatically a deletion. Likewise, an article with a changed slug may need a redirect from the old URL while only the new canonical URL appears in the sitemap.
Choose meaningful modification dates. A database timestamp updated by internal analytics should not claim the editorial content changed. Use a content modification field when available and document the fallback for legacy records. Avoid setting every entry to the current time on each request. That says little about which article actually changed.
Trace generation and caching
Read the sitemap function and identify its data source. A hardcoded array, build-time export, cached repository, and request-time database query have different freshness behavior. Inspect route configuration and deployment headers as well as the code. A fresh database result cannot help if a proxy serves an old XML response.
Create a synthetic article with a unique slug and publish it in an isolated environment. Compare the database, index, article route, and sitemap. Record how long the sitemap stays unchanged and what action refreshes it. This evidence distinguishes a stale collection query from a stale XML response.
Ask an AI assistant to trace the publishing operation to every invalidation call. Require it to show whether /sitemap.xml or the sitemap's data dependency is affected. A broad statement that publishing revalidates the blog is not proof that the sitemap shares the same cache entry.
Use one public projection
A sitemap needs only canonical slug and useful modification date. Query or project those fields directly instead of loading full bodies and populated authors. This keeps generation cheaper and limits accidental exposure. The projection should enforce the public inclusion rule before constructing entries.
import type { MetadataRoute } from 'next'
import { listPublishedArticleLocations } from '@/lib/articles'
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const rows = await listPublishedArticleLocations()
return rows.map(row => ({
url: new URL(`/blog/${row.slug}`, process.env.PUBLIC_SITE_ORIGIN).href,
lastModified: row.contentUpdatedAt
}))
}
This is an illustrative application mapper. Validate the configured public origin before startup or generation; a missing or malformed origin should fail clearly. The repository function must return valid dates and validated slugs. Do not infer the canonical origin from arbitrary request headers.
The resulting URLs should agree with article metadata. A sitemap pointing to one hostname while canonical links point to another creates avoidable ambiguity. Reuse a shared public URL constructor if the application has multiple discovery surfaces. Keep that constructor independent from private preview origins.
Make publication affect discovery
If the sitemap is intentionally cached, invalidate its route or data dependency after publication, withdrawal, slug changes, and meaningful edits. In Next.js 15.1.11, choose the available path or tag invalidation API and test its actual call context. Do not assume every open browser or external crawler refreshes immediately.
A time-based regeneration policy may be enough for a site that accepts delayed discovery. State the maximum intended delay and monitor it with a synthetic publish check. Explicit invalidation offers tighter control but can fail between a successful database write and cache update. Record or retry that failure if the publishing contract depends on it.
The same operation should remove withdrawn content from public lists. Avoid maintaining separate handwritten arrays for sitemap and index when both derive from the same database. Independent duplication creates drift that is easy for generated code to miss.
Verify XML and destination behavior
Fetch /sitemap.xml from the built deployment. Parse it as XML and confirm expected locations, escaping, and date values. A response with status 200 containing an HTML error page is not a usable sitemap. Check the response content type and ensure access controls do not require an administrator session.
Follow a representative set of listed URLs. They should resolve to public articles with matching canonical identity. Include a newly published record, an older record, a renamed record, and an optional-date case. Confirm drafts are absent. A test that only checks array length can pass while the wrong articles are listed.
For a larger corpus, check limits and partitioning rather than returning an unbounded dataset indefinitely. Next.js supports multiple sitemap generation patterns, while the sitemap protocol places limits on individual files. Use a deterministic partition strategy if needed and test that entries do not disappear at boundaries. Do not add partitioning before volume makes it necessary.
Keep monitoring factual
A sitemap is a discovery hint; its presence does not guarantee that a search engine indexes an article. Report what the application can verify: the public route exists, the sitemap includes it, canonical metadata agrees, and the response is reachable. Avoid invented indexing timelines or claims that a priority value forces ranking.
An AI-assisted review can compare published identifiers with parsed sitemap locations in a synthetic environment. Provide redacted data and ask for set differences, duplicates, and invalid dates. Let deterministic code perform the actual comparison. The assistant can explain anomalies, but the result should be reproducible without accepting its narrative.
If a sitemap fails during generation, expose that failure in deployment or monitoring. Silently returning an empty list keeps an endpoint alive while removing discovery. Choose whether a known previous valid sitemap is an acceptable fallback and record that it is stale.
Keep the publication journey coherent
The article route, blog index, metadata, and sitemap all describe the same public state. Build a small publication checklist around that state rather than separate implementation details. A publish should add the resource everywhere intended; a withdrawal should remove it everywhere intended.
Content freshness covers cache diagnosis, and metadata contracts covers canonical identity. A current sitemap completes that chain by advertising exactly the resources the site can publicly serve.
Sources
About the Author

Kamruz
Full Stack Developer
A passionate developer who loves creating modern web applications and sharing knowledge with the community.
More About Me