TLDR: Add export const dynamic = 'force-static' to your app/sitemap.ts file. This tells Next.js to generate the sitemap at build time instead of requiring a server.
You deployed your Next.js site as a static export to Cloudflare Pages, Netlify, or GitHub Pages. Everything works great.
Then you realize: search engines can't find your pages because you don't have a sitemap.
The problem? Most Next.js sitemap guides assume you're running a Node.js server. But static exports don't have a server.
Here's how to generate a sitemap that actually works with static exports.
The problem with Next.js static exports
When you use output: 'export' in Next.js, the framework builds your entire site as static HTML files. No server-side rendering, no API routes, no dynamic generation.
This is great for performance and hosting simplicity, but it breaks Next.js's built-in sitemap generation which expects dynamic route handlers.
The typical Next.js sitemap approach looks like this:
When you build with output: 'export', the dynamic route handler can't execute without a server. Your sitemap never generates.
The solution: force-static mode
Next.js has a configuration option that forces route handlers to generate at build time: force-static.
This tells Next.js to pre-render the sitemap during the build process instead of generating it on-demand.
Here's how it works:
The key line is export const dynamic = 'force-static'. This tells Next.js to generate sitemap.xml at build time as a static file.
Adding dynamic content from MDX files
For a blog or documentation site, you want your sitemap to include all your posts automatically.
Here's how to read your content files and add them to the sitemap:
Now update your sitemap to include all blog posts:
Verify the sitemap generates correctly
Build your site and check that the sitemap was created:
You should see a properly formatted XML file:
Deploy and test
Deploy your site to your static host. The sitemap should be accessible at:
Test it in your browser or use curl:
Submit to search engines
Once your sitemap is live, submit it to search engines:
Google Search Console:
- Go to https://search.google.com/search-console
- Select your property
- Navigate to Sitemaps
- Enter
sitemap.xmland submit
Bing Webmaster Tools:
- Go to https://www.bing.com/webmasters
- Add your site
- Submit your sitemap URL
You can also add it to your robots.txt:
Tip: You can also generate robots.txt dynamically using the same force-static approach with app/robots.ts.
Common issues and fixes
Issue: Sitemap not generating
Problem: The out directory doesn't contain sitemap.xml after building.
Solution: Make sure you're using force-static:
Issue: Build fails with "dynamic server usage"
Problem: Next.js complains about dynamic functions in your sitemap.
Solution: Don't use dynamic Next.js functions like cookies(), headers(), or searchParams in your sitemap. These require a server.
Adding projects or other content types
If you have multiple content directories (blog, projects, docs), follow the same pattern:
Then add to your sitemap:
Performance considerations
Sitemap generation happens at build time, not runtime. This means:
- No performance impact - The sitemap is a static file served directly by your CDN
- Rebuild to update - You need to rebuild and redeploy when you add new content
- No caching issues - The sitemap updates every time you build
For static sites, this is perfect. You're already rebuilding when you publish new content.
Takeaways
-
Use force-static - This is the key to making sitemaps work with static Next.js exports
-
Read content at build time - Use Node.js fs module to scan your MDX/MD files during the build
-
Filter drafts - Make sure to exclude draft posts from your sitemap
-
Test after building - Always verify the sitemap exists in your
outdirectory -
Submit to search engines - Don't forget to submit your sitemap to Google Search Console and Bing
-
Rebuild on content changes - Your sitemap only updates when you rebuild the site
Why this matters
Without a sitemap, search engines have to discover your pages by crawling links. This is slow and unreliable.
With a sitemap, you're explicitly telling search engines:
- Every page on your site
- When each page was last updated
- Which pages are most important
This helps your content get indexed faster and rank better in search results.
For a static blog or portfolio site, implementing a proper sitemap is one of the easiest SEO wins you can get.