Next.js 14 provided us with a simple way to take advantage of server side rendering and server actions. While this is one of my favorite additions to the modern framework, it does come with some adjustments that need to be made in the typical workflow. Thankfully, adding a dynamic sitemap is quite simple.
You may be asking why we aren't using the suggested method to dynamic sitemaps from Next.js. Well, If you are using server actions and the page where you are showing the blog post is using server side rendering, when you go to submit your sitemap to the google search console, you will find that google will not be able to fetch it. This is due to the sitemap being exclusive to the server. Furthermore, if you check on your deployed applications route for your sitemap, you may again find that your sitemap isn't showing like it does in your development environment. This is how I solved this issue.
Modern web applications built with Next.js require a dynamic approach to sitemaps. A sitemap helps search engines understand the structure and importance of your site's pages. While small applications with few pages might manage with a manual sitemap, larger applications with frequently updated content, like this website, require a programmatic solution to keep the sitemap updated.
First, install Next-sitemap.
npm i next-sitemap
Next, in your Next.js app create a new file app/server-sitemap.xml/route.ts:
import { getAllPosts } from '@/actions/actions'
import { getServerSideSitemap } from 'next-sitemap'
export async function GET(request: Request) {
// Method to source urls from cms
const urls = await getAllPosts()
const post = urls?.map((post:any) =>{
return{
loc: `https://www.example.com/blog/${post?.slug}`,
lastmod: post?.updatedAt.toISOString()
}
})
return getServerSideSitemap([
{
loc: `https://example.com`,
lastmod: new Date().toISOString(),
// changefreq
// priority
},
...post
])
}
I have a server action set up
getAllPosts()
that returns all of the blog posts. This could be your pictures or products, really whatever you want. You could also grab this from your api if you aren't using server actions.
Then we just map over each post, and add the url of each post and when it was last modified to an array I named post.
Finally we return the sitemap with the base url, then we spread each of the post objects in with it.
Now, if your project is running, head to
http://localhost:3000/server-sitemap.xml
and you should see your sitemap.
Conclusion
Writing web applications in Next.js with server side rendering paired with server actions will be my approach to development for the near future. Given the dynamic approach to using really any framework, it's important to keep in mind that solving problems like adding a sitemap may require a little bit more effort than using built-in features.
If you are interested in learning more aspects of SEO like keyword metadata, more reading is available on adding SEO to a Next.js project.