My site on Next.js 14 (App Router) has multi-language support and needs to generate sitemap.xml with:
<xhtml:link rel="alternate" hreflang="YOUR_LOCALE" href="YOUR_LINK" />
as Google shows in the following example: https://developers.google.com/search/docs/specialty/international/localized-versions#sitemap
How is it possible to do this?
In Next.js 14 (App Router) sitemap generation you can only specify 4 parameters that have nothing to do with localization: https://nextjs.org/docs/app/api-reference/file-conventions/metadata/sitemap
Or you can write sitemap.xml manually, but the site has product pages that are more than 2000 and manually doing it is crazy.
Maybe there is a way to build a string yourself? (getServerSideProps - not supported in App Router)
UPD: Thanks for solution Andrii Bodnar
Before the solution was worked out through the use of Route Handlers, where I returned the content as in sitemap.xml. Each folder with route.ts was named “sitemap.xml”. If dynamic routing was needed, it was just inside the folder, e.g. “[id]” - put the folder “sitemap.xml” with route.ts inside. For clarity, the structure is as follows:
.
└── sitemap.xml/
├── products/
│ ├── [id]/
│ │ └── sitemap.xml/
│ │ └── route.ts
│ └── sitemap.xml/
│ └── route.ts
└── route.ts
Version 14.2 of Next.js has been released. This version includes a lot of great features and improvements, including the localized Sitemap generation.
Now you can generate a localized sitemap as follows:
import { MetadataRoute } from 'next'
export default function sitemap(): MetadataRoute.Sitemap {
return [
{
url: 'https://acme.com',
lastModified: new Date(),
alternates: {
languages: {
es: 'https://acme.com/es',
de: 'https://acme.com/de',
},
},
},
{
url: 'https://acme.com/about',
lastModified: new Date(),
alternates: {
languages: {
es: 'https://acme.com/es/about',
de: 'https://acme.com/de/about',
},
},
},
]
}
Visit the official documentation for more details.