#Sitemap
$sitemap serves a sitemap.xml built from your $page primitives, and the build
prerenders it to a static file. You add one line to a router, and it follows the
pages from then on.
1import { $sitemap } from "alepha/react/sitemap";2 3class AppRouter {4 sitemap = $sitemap();5}
The route is GET /sitemap.xml. The build writes it to dist/public/sitemap.xml,
which is how a static site gets one. That file is
also what a built server answers with, because static files mount over the route,
so hostname and <lastmod> are the build's. alepha dev answers live. With
static: false the build writes no file, so a built server answers live too, and a
static site has no sitemap.
#Options
| Option | Default | What it does |
|---|---|---|
hostname |
PUBLIC_URL, else "" |
The base of every URL. Empty, the URLs are relative. |
urls |
[] |
Extra URLs to list after the pages. |
path |
/sitemap.xml |
Where it is served. |
static |
true |
Whether the build prerenders it to a file. |
⚠️ A sitemap is meant to hold absolute URLs, so set hostname or PUBLIC_URL. A
prerendered file is written at build time, so PUBLIC_URL must be set then.
#Which pages it lists
It reads the router's compiled routes, so a nested page appears at the path a visitor requests, with its layouts in front of it.
| Page | Listed |
|---|---|
| A page with no parameter | Yes. |
| A page with a parameter, its own or a layout's | Only through static.entries, see below. |
| A layout (a page with children) | No. |
| A path with a wildcard | No. |
/404 |
No. |
There is no option to leave out one page, and a $secure page with no parameter
is listed like any other.
#Pages with parameters
A page with parameters is listed once per entry of its static.entries:
1import { z } from "alepha"; 2import { $page } from "alepha/react/router"; 3import { $sitemap } from "alepha/react/sitemap"; 4 5class BlogRouter { 6 post = $page({ 7 path: "/blog/:slug", 8 schema: { params: z.object({ slug: z.text() }) }, 9 static: {10 entries: [11 { params: { slug: "hello-world" } },12 { params: { slug: "second-post" } },13 ],14 },15 component: () => null,16 });17 18 sitemap = $sitemap({ hostname: "https://myapp.com" });19}
Values are percent-encoded. An entry that leaves a parameter unfilled, such as a
parent's :orgId, is skipped, since a URL holding :orgId is not a URL.
#URLs that are not pages
urls lists what no $page answers, a feed or an llms.txt. A path is joined to
the hostname, and an absolute URL is listed as it is:
1import { $sitemap } from "alepha/react/sitemap";2 3class AppRouter {4 sitemap = $sitemap({5 hostname: "https://myapp.com",6 urls: ["/llms.txt", "/feed.xml", "https://docs.myapp.com/"],7 });8}
#What it writes
A standard urlset, one <url> per entry, each with a <loc> and a <lastmod>.
<lastmod> is the date the sitemap was generated, the same for every URL: it says
nothing about when a page changed.
$sitemap does nothing in the browser, so it can sit on an isomorphic router class.