Site name: https://main--frabjous-sherbet-71a682.netlify.app/
I have a Next.js 13 app. I generate the sitemap.xml with a .js file using the approach in the Next.js docs
When I do a production build locally the sitemap generates correctly & I can see all the entries in the .xml file.
When I deploy to Netlify some of the entries from the sitemap.xml file are missing. I can console log those entries in the build log when the sitemap generator js file runs and they’re all present in the correct format. I also don’t see any issues in the build log. I’m pretty sure it’s some sort of a post processing issue because during the build it looks like it’s picking up the right values.
I’m using all the default config provided by Netlify for a next.js app. I only added a few env variables for contentful.
That would depend on the generation logic. How are you generating the sitemap exactly?
Hey hrishikesh,
Sorry about the later response!
Based on my description I do understand that it sounds like a mistake in the generation logic. However, in that case I would expect those specific entries to be missing in a local production build as well and I wouldn’t be able to console log them during the Netlify build and see the correct entries in the build log.
Anyways, I’ll attach the file if you could have a look that would be helpful. I use Next.js 13 and added the sitemap.ts file to the /app folder as recommended in the next.js docs.
The script runs during build (npm run build)
import { globby } from "globby"
import { getAllPortfolioItemsForSitemapByTags } from "lib/contenful-cms/model/portfolio/sitemap"
export default async function sitemap() {
let pages = await globby(["app/**/page{.ts,.tsx,.mdx}", "!app/**/[id]/page{.ts,.tsx,.mdx}"])
console.log(pages)
const [photos, graphics] = await Promise.all([getAllPortfolioItemsForSitemapByTags(["photo"]), getAllPortfolioItemsForSitemapByTags(["graphics"])])
if (!graphics || !photos) throw new Error("There was an error while retrieving portfolio items for sitemap")
const dynamicPages = [...graphics.map((item) => `/graphics/${item.slug}`), ...photos.map((item) => `/photo/${item.slug}`)]
const staticPages = pages.map(formatPage)
pages = [...staticPages, ...dynamicPages]
const domains = ["https://www.domain.hu", "https://www.domain2.com"]
console.log(staticPages)
console.log(dynamicPages)
console.log(pages)
const output = domains
.map((domain) =>
pages.map((route) => ({
url: `${domain}${route}`,
lastModified: new Date().toISOString(),
}))
)
.flat()
console.log(output)
return output
}
function formatPage(page: string) {
const formatted = page.replace("app", "").replace("/(home)", "").replace("/page", "").replace(".tsx", "").replace(".ts", "")
console.log(formatted)
return formatted
}
Just to be more specific the entries that are missing from the deployed version (sitemap.xml) are the ones coming from the staticPages
variable so basically the ones read from the file system. Asynchronous values are present in the output xml correctly.
That would explain it. Server-side functionality is executed in Lambda, and your local files are not included there - at least by default. So there would be no files matching that globs. Check out: How to Include Files in Netlify Serverless Functions. The name of the function would be ___netlify-handler
.
1 Like
Thanks hrishikesh you saved my day! This was the issue and I was able to resolve it by updating the deployment config with the missing file paths for the function.
Just for other people running into similar issues - the solution was to create a netlify.toml file in the root directory and add the following lines:
[functions]
[functions.___netlify-handler]
included_files = [
"app/**/page{.ts,.tsx,.mdx}",
"!app/**/[id]/page{.ts,.tsx,.mdx}"
]
This didn’t override the default config on any level only extended it.
Useful resources:
Note:
Just to simplify the solution I ended up creating a JS object that includes all my static paths (I needed them in the site navigation logic anyways) and import that for the sitemap generator so I don’t have to read from the file system anymore.