How to generate a Sitemap in React Router 7 and Remix
Learn how to automatically generate a sitemap.xml file for your React Router 7 or Remix app using minimal configuration with this step-by-step guide.
If you’re building a website or web application, you’ll want to make sure your site is discoverable by search engines. One essential step is providing a sitemap that lists all your public routes.
Manually maintaining a sitemap is tedious and error-prone. By generating it from your route definitions, you ensure it’s always up-to-date and accurate.
#Prerequisites
- A project using React Router 7 or Remix.
- Access to your route definitions via
virtual:react-router/server-buildorvirtual:remix/server-build.
#Install the @forge42/seo-tools package
First, install the @forge42/seo-tools package. This library provides utilities for handling SEO-related tasks and has a dedicated @forge42/seo-tools/remix export that works with Remix and React Router 7 applications.
npm install @forge42/seo-tools#Create the resource route for the sitemap
Create a file at app/routes/sitemap.xml.ts. This will be the resource route and exports a loader that generates the sitemap on demand:
import { generateRemixSitemap } from "@forge42/seo-tools/remix/sitemap";
import type { Route } from "./+types/sitemap.xml";
import { href } from "react-router";
export const loader = async ({ request }: Route.LoaderArgs) => {
const { routes } = await import("virtual:react-router/server-build");
const { origin } = new URL(request.url);
const sitemap = await generateRemixSitemap({
domain: origin,
ignore: [href("/api/chat"), href("/legal-notice"), href("/privacy-policy")],
// @ts-expect-error Type mismatch, maybe related to a stricter type mentioned in release notes for v.7.0.0
// https://github.com/forge-42/seo-tools/issues/8
routes,
});
return new Response(sitemap, {
headers: {
"Content-Type": "application/xml",
},
});
};#What’s happening here?
- Dynamically import
virtual:react-router/server-buildto get your route definitions.Info Since React Router v7.4.0, the
virtual:react-router/server-buildmodule is type safe and you can destructure yourroutesobject from it. - The
generateRemixSitemap()helper function takes your route definitions and creates a valid sitemap.Info Because the package is build for Remix v2, the function automatically looks for routes in
virtual:remix/server-build, but with React Router 7, the correct module would bevirtual:react-router/server-build. That’s why we have to import theroutesin the previous step by hand. I already opened an issue to get native support for React Router 7. - The
ignoreoption excludes routes you don’t want indexed (like API endpoints or legal pages).I prefer using theWhy ignore some routes? Not every route should be indexed by search engines. Exclude API endpoints, admin pages, or anything private.
href()function from React Router 7 for type-safe paths.Tip The
hreffunction was introduced in React Router v7.2.0 and ensures type safety for your links. - The
domainoption specifies the domain for your URLs. Using the request’soriginshould work in any environment. - The response returns the sitemap as XML with the correct content type.
For more information and advanced usage, check out the official documentation.
#Register the route
Make sure the route is included in your route config:
export default [
// ...
route("sitemap.xml", "routes/sitemap.xml.ts"),
] satisfies RouteConfig;Now, visiting /sitemap.xml in your browser will return a fresh, up-to-date sitemap!
When using the package, I found the home route (/) was registered multiple
times in the sitemap. See issue
#12.
#Test your sitemap
Visit /sitemap.xml in your browser or use an online validator to check that your sitemap is valid and includes all the right routes.
#Submit the sitemap to search engines
To have your sitemap indexed, you should submit it to search engines. Most will discover it if you link to it from your robots.txt, but submitting directly is more reliable.
- For Google, use Search Console.
- For Bing, use Bing Webmaster Tools.