I’m building a Next.js app deployed on Vercel, and I’ve implemented a dynamic sitemap generator in /src/app/sitemap.ts. The sitemap is generated by scanning markdown files in a _posts directory located in the root of my project. Here's my code:
import fs from 'fs';
import { join } from 'path';
import { MetadataRoute } from 'next';
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const blogPosts = fs.readdirSync(join(process.cwd(), '_posts'));
const blogPostPages: MetadataRoute.Sitemap = blogPosts.map((post) => ({
url: `${url}${post}`,
lastModified: getLastModified(`_posts/${post}.md`),
changeFrequency: 'daily',
priority: 1,
}));
return blogPostPages;
}
This works perfectly in my local environment. However, when I deploy the app to Vercel, I get the following error:
Error: ENOENT: no such file or directory, scandir '/var/task/_posts'
It seems like the _posts directory isn’t accessible or doesn’t exist in the Vercel deployment environment.
Additional Context
- _posts contains markdown files (post1.md, post2.md, etc.).
- The app is deployed on Vercel using their default build pipeline.
Questions
- Why does this error occur on Vercel but not locally?
- How can I ensure the _posts directory is available in the deployed environment?
- Is there a better way to dynamically generate a sitemap in Next.js that works seamlessly on Vercel?