Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,8 @@ export const handle: SitemapHandle<SitemapData> = {
}
```

This applies to all routes, including `root.tsx`. The `root.tsx` sitemap function acts as a fallback and will run for any route that does not define its own sitemap handle.

### Handling sitemap index + dynamic sitemaps + robots.txt

If you want to generate different sitemaps based on the language you can use the following approach:
Expand Down
32 changes: 24 additions & 8 deletions src/remix/sitemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ const createExtendedRoutes = (routes: RouteManifest<InternalServerRoute | undefi
}
})
}

const hasSitemapHandle = (handle: unknown): handle is { sitemap: SitemapFunction<unknown> } => {
return Boolean(handle && typeof handle === "object" && "sitemap" in handle && typeof handle.sitemap === "function")
}

const generateRemixSitemapRoutes = async ({
domain,
sitemapData,
Expand All @@ -54,21 +59,32 @@ const generateRemixSitemapRoutes = async ({
// Add the url to each route
const extendedRoutes = createExtendedRoutes(routes)

const rootRoute = extendedRoutes.find(({ id }) => id === "root")
const rootHandle = rootRoute?.module?.handle

const hasRootHandle = hasSitemapHandle(rootHandle)

const transformedRoutes = await Promise.all(
extendedRoutes.map(async (route) => {
const url = route.url
// We don't want to include the root route in the sitemap
if (route.id === "root") return
// If the route has a module, get the handle

const url = route.url
const handle = route.module?.handle
// If the route has a sitemap function, call it and return the sitemap entries
if (handle && typeof handle === "object" && "sitemap" in handle && typeof handle.sitemap === "function") {
// Type the function just in case
const sitemap = handle.sitemap as SitemapFunction<unknown>
const sitemapEntries: SitemapFunctionReturnData = await sitemap(domain, url, sitemapData)

// Run the route sitemap function if it exists
if (hasSitemapHandle(handle)) {
const sitemapEntries = await handle.sitemap(domain, url, sitemapData)
return { url, sitemapEntries, id: route.id }
}

// As a fallback run the root route sitemap function
if (hasRootHandle) {
const sitemapEntries = await rootHandle.sitemap(domain, url, sitemapData)
return { url, sitemapEntries, id: route.id }
}
// Otherwise, just return the route as a single entry

// If no sitemap function was found, just return the route as a single entry
return { url, sitemapEntries: null, id: route.id }
})
)
Expand Down