Sitemap support is officially included in the Epic Stack now: https://github.com/epicweb-dev/epic-stack/blob/main/docs/seo.md
Often sitemaps are not necessary, however, for sites highly sensitive to search engines, or sites with a lot of content, they can be very useful.
The Epic Stack does not include sitemaps by default (read the decision doc on sitemaps), but following this example should allow you to get an autogenerated sitemap up and going in no time.
The most important bits are:
- The
app/utils/sitemap.server.ts
file which is the brains of the generation - The change in
app/entry.server.tsx
which allows the sitemap to be generated on demand - Add the sitemap to your robots.txt
By applying these changes to your codebase, all routes will be added to the sitemap with the exception of:
- Resource Routes - Those aren't typically meant to be indexed
- Dynamic segment routes - We don't have enough information to automatically generate anything useful for those.
To customize the sitemap entry and add entries for dynamic routes, the sitemap
generation here uses a feature from Remix called
handle
which allows you to
associate arbitrary information with any route. Here's an example of how we add
entries for every user's profile page:
// app/routes/users+/$username.tsx
// ...
export const handle: SitemapHandle = {
async getSitemapEntries({ request }) {
const users = await prisma.user.findMany({
select: { username: true, updatedAt: true },
})
return users.map(user => ({
changefreq: 'monthly',
priority: 0.5,
lastmod: user.updatedAt,
route: `/users/${user.username}`,
}))
},
}
And here's how we disable the sitemap for everything under /admin
// app/routes/admin+/_layout.tsx
import { type SitemapHandle } from '~/utils/sitemap.server.ts'
export const handle: SitemapHandle = {
getSitemapEntries: null,
}
There are a few examples of enabling and disabling the sitemap. We add a parent
route for the /admin
routes to disable the sitemap for all routes in that path
and below. We also add some config for the homepage as well.
Checkout the git commit history to get a sense for what you can do with this.