1 import { getPageMap } from 'nextra/page-map'
2
3 const BASE_URL = 'https://docs.smbcloud.xyz'
4
5 /**
6 * Collect every real page route from Nextra's page map.
7 *
8 * The map mixes three kinds of entry: `_meta` files (a bare `data` object),
9 * folders (a `route` plus `children`), and pages (a `route`). Folders here use
10 * `asIndexPage` frontmatter, so they resolve to a real page too and belong in
11 * the sitemap — but a folder without its own page would still carry a `route`,
12 * so we only emit entries Nextra gave a `name` (pages and index pages), never
13 * the synthetic separators declared in `_meta.js`.
14 */
15 function collectRoutes(pageMap, seen = new Set()) {
16 for (const item of pageMap) {
17 if (!item || item.data) continue
18 if (typeof item.route === 'string' && item.name) {
19 seen.add(item.route)
20 }
21 if (Array.isArray(item.children)) {
22 collectRoutes(item.children, seen)
23 }
24 }
25 return seen
26 }
27
28 // Shallower pages are the entry points people and crawlers land on first.
29 // Google largely ignores `priority`, but it costs nothing and it keeps the
30 // hierarchy explicit for the crawlers that still read it.
31 function priorityFor(route) {
32 if (route === '/') return 1
33 const depth = route.split('/').filter(Boolean).length
34 if (depth === 1) return 0.8
35 if (depth === 2) return 0.7
36 return 0.6
37 }
38
39 export default async function sitemap() {
40 const pageMap = await getPageMap()
41 const routes = [...collectRoutes(pageMap)].sort()
42
43 return routes.map(route => ({
44 url: `${BASE_URL}${route === '/' ? '' : route}`,
45 changeFrequency: 'weekly',
46 priority: priorityFor(route)
47 }))
48 }