docs: add sitemap.xml

This commit is contained in:
Nicolas Meienberger
2026-04-18 11:09:56 +02:00
parent c5e35cf8b1
commit e19776a2b8
3 changed files with 61 additions and 3 deletions

View File

@@ -1,3 +1,4 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
Sitemap: https://zerobyte.app/sitemap.xml

View File

@@ -9,10 +9,16 @@
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
import { Route as rootRouteImport } from './routes/__root'
import { Route as SitemapDotxmlRouteImport } from './routes/sitemap[.]xml'
import { Route as IndexRouteImport } from './routes/index'
import { Route as DocsSplatRouteImport } from './routes/docs/$'
import { Route as ApiSearchRouteImport } from './routes/api/search'
const SitemapDotxmlRoute = SitemapDotxmlRouteImport.update({
id: '/sitemap.xml',
path: '/sitemap.xml',
getParentRoute: () => rootRouteImport,
} as any)
const IndexRoute = IndexRouteImport.update({
id: '/',
path: '/',
@@ -31,36 +37,47 @@ const ApiSearchRoute = ApiSearchRouteImport.update({
export interface FileRoutesByFullPath {
'/': typeof IndexRoute
'/sitemap.xml': typeof SitemapDotxmlRoute
'/api/search': typeof ApiSearchRoute
'/docs/$': typeof DocsSplatRoute
}
export interface FileRoutesByTo {
'/': typeof IndexRoute
'/sitemap.xml': typeof SitemapDotxmlRoute
'/api/search': typeof ApiSearchRoute
'/docs/$': typeof DocsSplatRoute
}
export interface FileRoutesById {
__root__: typeof rootRouteImport
'/': typeof IndexRoute
'/sitemap.xml': typeof SitemapDotxmlRoute
'/api/search': typeof ApiSearchRoute
'/docs/$': typeof DocsSplatRoute
}
export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath
fullPaths: '/' | '/api/search' | '/docs/$'
fullPaths: '/' | '/sitemap.xml' | '/api/search' | '/docs/$'
fileRoutesByTo: FileRoutesByTo
to: '/' | '/api/search' | '/docs/$'
id: '__root__' | '/' | '/api/search' | '/docs/$'
to: '/' | '/sitemap.xml' | '/api/search' | '/docs/$'
id: '__root__' | '/' | '/sitemap.xml' | '/api/search' | '/docs/$'
fileRoutesById: FileRoutesById
}
export interface RootRouteChildren {
IndexRoute: typeof IndexRoute
SitemapDotxmlRoute: typeof SitemapDotxmlRoute
ApiSearchRoute: typeof ApiSearchRoute
DocsSplatRoute: typeof DocsSplatRoute
}
declare module '@tanstack/react-router' {
interface FileRoutesByPath {
'/sitemap.xml': {
id: '/sitemap.xml'
path: '/sitemap.xml'
fullPath: '/sitemap.xml'
preLoaderRoute: typeof SitemapDotxmlRouteImport
parentRoute: typeof rootRouteImport
}
'/': {
id: '/'
path: '/'
@@ -87,6 +104,7 @@ declare module '@tanstack/react-router' {
const rootRouteChildren: RootRouteChildren = {
IndexRoute: IndexRoute,
SitemapDotxmlRoute: SitemapDotxmlRoute,
ApiSearchRoute: ApiSearchRoute,
DocsSplatRoute: DocsSplatRoute,
}

View File

@@ -0,0 +1,39 @@
import { createFileRoute } from "@tanstack/react-router";
import { source } from "@/lib/source";
const siteUrl = "https://zerobyte.app";
function escapeXml(value: string) {
return value
.replaceAll("&", "&")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll('"', "&quot;")
.replaceAll("'", "&apos;");
}
function buildSitemapXml(urls: string[]) {
const entries = urls.map((url) => ` <url>\n <loc>${escapeXml(url)}</loc>\n </url>`).join("\n");
return `<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n${entries}\n</urlset>`;
}
export const Route = createFileRoute("/sitemap.xml")({
server: {
handlers: {
GET: async () => {
const urls = Array.from(new Set(["/", ...source.getPages().map((page) => page.url)]))
.sort()
.map((path) => new URL(path, siteUrl).toString());
return new Response(buildSitemapXml(urls), {
headers: {
"Content-Type": "application/xml; charset=utf-8",
"Cache-Control": "public, max-age=3600",
},
});
},
},
},
});