docs: add sitemap.xml
This commit is contained in:
parent
c5e35cf8b1
commit
e19776a2b8
3 changed files with 61 additions and 3 deletions
|
|
@ -1,3 +1,4 @@
|
||||||
# https://www.robotstxt.org/robotstxt.html
|
# https://www.robotstxt.org/robotstxt.html
|
||||||
User-agent: *
|
User-agent: *
|
||||||
Disallow:
|
Disallow:
|
||||||
|
Sitemap: https://zerobyte.app/sitemap.xml
|
||||||
|
|
|
||||||
|
|
@ -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.
|
// 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 rootRouteImport } from './routes/__root'
|
||||||
|
import { Route as SitemapDotxmlRouteImport } from './routes/sitemap[.]xml'
|
||||||
import { Route as IndexRouteImport } from './routes/index'
|
import { Route as IndexRouteImport } from './routes/index'
|
||||||
import { Route as DocsSplatRouteImport } from './routes/docs/$'
|
import { Route as DocsSplatRouteImport } from './routes/docs/$'
|
||||||
import { Route as ApiSearchRouteImport } from './routes/api/search'
|
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({
|
const IndexRoute = IndexRouteImport.update({
|
||||||
id: '/',
|
id: '/',
|
||||||
path: '/',
|
path: '/',
|
||||||
|
|
@ -31,36 +37,47 @@ const ApiSearchRoute = ApiSearchRouteImport.update({
|
||||||
|
|
||||||
export interface FileRoutesByFullPath {
|
export interface FileRoutesByFullPath {
|
||||||
'/': typeof IndexRoute
|
'/': typeof IndexRoute
|
||||||
|
'/sitemap.xml': typeof SitemapDotxmlRoute
|
||||||
'/api/search': typeof ApiSearchRoute
|
'/api/search': typeof ApiSearchRoute
|
||||||
'/docs/$': typeof DocsSplatRoute
|
'/docs/$': typeof DocsSplatRoute
|
||||||
}
|
}
|
||||||
export interface FileRoutesByTo {
|
export interface FileRoutesByTo {
|
||||||
'/': typeof IndexRoute
|
'/': typeof IndexRoute
|
||||||
|
'/sitemap.xml': typeof SitemapDotxmlRoute
|
||||||
'/api/search': typeof ApiSearchRoute
|
'/api/search': typeof ApiSearchRoute
|
||||||
'/docs/$': typeof DocsSplatRoute
|
'/docs/$': typeof DocsSplatRoute
|
||||||
}
|
}
|
||||||
export interface FileRoutesById {
|
export interface FileRoutesById {
|
||||||
__root__: typeof rootRouteImport
|
__root__: typeof rootRouteImport
|
||||||
'/': typeof IndexRoute
|
'/': typeof IndexRoute
|
||||||
|
'/sitemap.xml': typeof SitemapDotxmlRoute
|
||||||
'/api/search': typeof ApiSearchRoute
|
'/api/search': typeof ApiSearchRoute
|
||||||
'/docs/$': typeof DocsSplatRoute
|
'/docs/$': typeof DocsSplatRoute
|
||||||
}
|
}
|
||||||
export interface FileRouteTypes {
|
export interface FileRouteTypes {
|
||||||
fileRoutesByFullPath: FileRoutesByFullPath
|
fileRoutesByFullPath: FileRoutesByFullPath
|
||||||
fullPaths: '/' | '/api/search' | '/docs/$'
|
fullPaths: '/' | '/sitemap.xml' | '/api/search' | '/docs/$'
|
||||||
fileRoutesByTo: FileRoutesByTo
|
fileRoutesByTo: FileRoutesByTo
|
||||||
to: '/' | '/api/search' | '/docs/$'
|
to: '/' | '/sitemap.xml' | '/api/search' | '/docs/$'
|
||||||
id: '__root__' | '/' | '/api/search' | '/docs/$'
|
id: '__root__' | '/' | '/sitemap.xml' | '/api/search' | '/docs/$'
|
||||||
fileRoutesById: FileRoutesById
|
fileRoutesById: FileRoutesById
|
||||||
}
|
}
|
||||||
export interface RootRouteChildren {
|
export interface RootRouteChildren {
|
||||||
IndexRoute: typeof IndexRoute
|
IndexRoute: typeof IndexRoute
|
||||||
|
SitemapDotxmlRoute: typeof SitemapDotxmlRoute
|
||||||
ApiSearchRoute: typeof ApiSearchRoute
|
ApiSearchRoute: typeof ApiSearchRoute
|
||||||
DocsSplatRoute: typeof DocsSplatRoute
|
DocsSplatRoute: typeof DocsSplatRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module '@tanstack/react-router' {
|
declare module '@tanstack/react-router' {
|
||||||
interface FileRoutesByPath {
|
interface FileRoutesByPath {
|
||||||
|
'/sitemap.xml': {
|
||||||
|
id: '/sitemap.xml'
|
||||||
|
path: '/sitemap.xml'
|
||||||
|
fullPath: '/sitemap.xml'
|
||||||
|
preLoaderRoute: typeof SitemapDotxmlRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
'/': {
|
'/': {
|
||||||
id: '/'
|
id: '/'
|
||||||
path: '/'
|
path: '/'
|
||||||
|
|
@ -87,6 +104,7 @@ declare module '@tanstack/react-router' {
|
||||||
|
|
||||||
const rootRouteChildren: RootRouteChildren = {
|
const rootRouteChildren: RootRouteChildren = {
|
||||||
IndexRoute: IndexRoute,
|
IndexRoute: IndexRoute,
|
||||||
|
SitemapDotxmlRoute: SitemapDotxmlRoute,
|
||||||
ApiSearchRoute: ApiSearchRoute,
|
ApiSearchRoute: ApiSearchRoute,
|
||||||
DocsSplatRoute: DocsSplatRoute,
|
DocsSplatRoute: DocsSplatRoute,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
39
apps/docs/src/routes/sitemap[.]xml.ts
Normal file
39
apps/docs/src/routes/sitemap[.]xml.ts
Normal 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("<", "<")
|
||||||
|
.replaceAll(">", ">")
|
||||||
|
.replaceAll('"', """)
|
||||||
|
.replaceAll("'", "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
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",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
Loading…
Reference in a new issue