Outstatic Sitemap
OutstaticsitemapNextJs

Outstatic Sitemap


The default Outstatic blog template doesn't generate a sitemap, which is an easy thing to miss until you check your search console and find nothing indexed. Adding one is trivial with the Next.js App Router — you drop a sitemap.(js|ts) file anywhere in the app and export a function that returns an array of URLs. If you're on TypeScript, there's a Sitemap type.

import { MetadataRoute } from "next";
import { NEXT_PUBLIC_APP_URL } from "../lib/constants";
import { load } from "outstatic/server";
 
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
  const db = await load();
  const items = await db
    .find(
      { collection: "posts", status: "published" },
      ["slug", "publishedAt"],
    )
    .toArray();
 
  return items.map((item) => ({
    url: `${NEXT_PUBLIC_APP_URL}/${item.slug}`,
    lastModified: item.publishedAt,
  }));
}

Next.js generates the XML at build time and serves it at ahlstrand.es/sitemap.xml:

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>http://localhost:3000/rest-api-guidelines</loc>
    <lastmod>2024-06-06T06:22:28.823Z</lastmod>
  </url>
  <url>
    <loc>http://localhost:3000/oauth2-endpoints-parameters</loc>
    <lastmod>2024-06-07T09:20:42.889Z</lastmod>
  </url>
  ...
</urlset>

Since this function already iterates over every post, it's also a convenient place to build a FlexSearch index during the same pass — which is what I ended up doing. More on that in the follow-up post.