generate-sitemap.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #!/usr/bin/env bun
  2. import { readdir, writeFile } from "fs/promises"
  3. import { join, dirname } from "path"
  4. import { fileURLToPath } from "url"
  5. import { config } from "../src/config.js"
  6. import { LOCALES, route } from "../src/lib/language.js"
  7. const __dirname = dirname(fileURLToPath(import.meta.url))
  8. const BASE_URL = config.baseUrl
  9. const PUBLIC_DIR = join(__dirname, "../public")
  10. const ROUTES_DIR = join(__dirname, "../src/routes")
  11. const DOCS_DIR = join(__dirname, "../../../web/src/content/docs")
  12. interface SitemapEntry {
  13. url: string
  14. priority: number
  15. changefreq: string
  16. }
  17. async function getMainRoutes(): Promise<SitemapEntry[]> {
  18. const routes: SitemapEntry[] = []
  19. // Add main static routes
  20. const staticRoutes = [
  21. { path: "/", priority: 1.0, changefreq: "daily" },
  22. { path: "/enterprise", priority: 0.8, changefreq: "weekly" },
  23. { path: "/brand", priority: 0.6, changefreq: "monthly" },
  24. { path: "/zen", priority: 0.8, changefreq: "weekly" },
  25. ]
  26. for (const item of staticRoutes) {
  27. for (const locale of LOCALES) {
  28. routes.push({
  29. url: `${BASE_URL}${route(locale, item.path)}`,
  30. priority: item.priority,
  31. changefreq: item.changefreq,
  32. })
  33. }
  34. }
  35. return routes
  36. }
  37. async function getDocsRoutes(): Promise<SitemapEntry[]> {
  38. const routes: SitemapEntry[] = []
  39. try {
  40. const files = await readdir(DOCS_DIR)
  41. for (const file of files) {
  42. if (!file.endsWith(".mdx")) continue
  43. const slug = file.replace(".mdx", "")
  44. const path = slug === "index" ? "/docs/" : `/docs/${slug}`
  45. for (const locale of LOCALES) {
  46. routes.push({
  47. url: `${BASE_URL}${route(locale, path)}`,
  48. priority: slug === "index" ? 0.9 : 0.7,
  49. changefreq: "weekly",
  50. })
  51. }
  52. }
  53. } catch (error) {
  54. console.error("Error reading docs directory:", error)
  55. }
  56. return routes
  57. }
  58. function generateSitemapXML(entries: SitemapEntry[]): string {
  59. const urls = entries
  60. .map(
  61. (entry) => ` <url>
  62. <loc>${entry.url}</loc>
  63. <changefreq>${entry.changefreq}</changefreq>
  64. <priority>${entry.priority}</priority>
  65. </url>`,
  66. )
  67. .join("\n")
  68. return `<?xml version="1.0" encoding="UTF-8"?>
  69. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  70. ${urls}
  71. </urlset>`
  72. }
  73. async function main() {
  74. console.log("Generating sitemap...")
  75. const mainRoutes = await getMainRoutes()
  76. const docsRoutes = await getDocsRoutes()
  77. const allRoutes = [...mainRoutes, ...docsRoutes]
  78. console.log(`Found ${mainRoutes.length} main routes`)
  79. console.log(`Found ${docsRoutes.length} docs routes`)
  80. console.log(`Total: ${allRoutes.length} routes`)
  81. const xml = generateSitemapXML(allRoutes)
  82. const outputPath = join(PUBLIC_DIR, "sitemap.xml")
  83. await writeFile(outputPath, xml, "utf-8")
  84. console.log(`✓ Sitemap generated at ${outputPath}`)
  85. }
  86. main()