DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

Burhan Haroon
Burhan Haroon

Posted on

How to generate /sitemap.xml route in Remix framework

According to google.com

A sitemap is a file where you provide information about the pages, videos, and other files on your site, and the relationships between them. Search engines like Google read this file to crawl your site more efficiently.

First of all we are going to need the help of this very powerful package named Remix SEO. So, install it by using the following command.

npm i @balavishnuvj/remix-seo
Enter fullscreen mode Exit fullscreen mode

Then make a new file named sitemapRoutes.server.ts within our app/ directory. After creating the file paste the following code there.

import type { EntryContext } from "@remix-run/node";
import { generateSitemap } from "@balavishnuvj/remix-seo";

const siteUrl =
  process.env.ENVIRONMENT === "production"
    ? "https://yourProductionWebsiteUrl.com"
    : "http://localhost:3000";

type Handler = (
  request: Request,
  remixContext: EntryContext
) => Promise<Response | null> | null;

export const otherRootRoutes: Record<string, Handler> = {
  "/sitemap.xml": async (request, remixContext) => {
    return generateSitemap(request, remixContext, {
      siteUrl,
    });
  },
};

export const otherRootRouteHandlers: Array<Handler> = [
  ...Object.entries(otherRootRoutes).map(([path, handler]) => {
    return (request: Request, remixContext: EntryContext) => {
      if (new URL(request.url).pathname !== path) return null;

      return handler(request, remixContext);
    };
  }),
];

Enter fullscreen mode Exit fullscreen mode

That's it for the sitemapRoutes.server.ts file. Now head to the entry.server.tsx file in the app/ directory and make the following changes there:

import type { EntryContext } from "@remix-run/node";
import { RemixServer } from "@remix-run/react";
import { renderToString } from "react-dom/server";
+ import { otherRootRouteHandlers } from "./sitemapRoutes.server";


- export default function handleRequest(
+ export default async function handleRequest(
  request: Request,
  responseStatusCode: number,
  responseHeaders: Headers,
  remixContext: EntryContext
) {
+  for (const handler of otherRootRouteHandlers) {
+    const otherRouteResponse = await handler(request, remixContext);
+    if (otherRouteResponse) return otherRouteResponse;
+  }
  const markup = renderToString(
    <RemixServer context={remixContext} url={request.url} />
  );

  responseHeaders.set("Content-Type", "text/html");

  return new Response("<!DOCTYPE html>" + markup, {
    status: responseStatusCode,
    headers: responseHeaders,
  });
}
Enter fullscreen mode Exit fullscreen mode

and now you're done! Congratulations you did it ;)
Now you just have to goto http://localhost:3000/sitemap.xml link and you'll see the sitemap generated like this:

sitemap.xml

Top comments (5)

Collapse
numananees profile image
Numan Anees • Edited on

For generating the siteURL dynamically you can also use the following code.

 const host =
      request.headers.get("X-Forwarded-Host") ?? request.headers.get("host");
    if (!host) {
      throw new Error("Could not determine domain URL.");
    }
    const protocol = host.includes("localhost") ? "http" : "https";
    const siteUrl = `${protocol}://${host}`;
Enter fullscreen mode Exit fullscreen mode
Collapse
burhanharoon profile image
Burhan Haroon Author

Thanks for the suggestion. I'll add that up to the article. Thanks again! Cheers!

Collapse
zubairgujjar997 profile image
Muhammad Zubair

At This Level , I am Unable to Understand This , But This Might be Very Interesting and Useful

Collapse
burhanharoon profile image
Burhan Haroon Author

InshAllah you'll very soon. I know it.

Collapse
zubairgujjar997 profile image
Muhammad Zubair

Thanks Sir ☺️

🌚 Friends don't let friends browse without dark mode.

Sorry, it's true.