generate-sitemap.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  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. { path: "/go", priority: 0.8, changefreq: "weekly" },
  26. ]
  27. for (const item of staticRoutes) {
  28. for (const locale of LOCALES) {
  29. routes.push({
  30. url: `${BASE_URL}${route(locale, item.path)}`,
  31. priority: item.priority,
  32. changefreq: item.changefreq,
  33. })
  34. }
  35. }
  36. return routes
  37. }
  38. async function getDocsRoutes(): Promise<SitemapEntry[]> {
  39. const routes: SitemapEntry[] = []
  40. try {
  41. const files = await readdir(DOCS_DIR)
  42. for (const file of files) {
  43. if (!file.endsWith(".mdx")) continue
  44. const slug = file.replace(".mdx", "")
  45. const path = slug === "index" ? "/docs/" : `/docs/${slug}`
  46. for (const locale of LOCALES) {
  47. routes.push({
  48. url: `${BASE_URL}${route(locale, path)}`,
  49. priority: slug === "index" ? 0.9 : 0.7,
  50. changefreq: "weekly",
  51. })
  52. }
  53. }
  54. } catch (error) {
  55. console.error("Error reading docs directory:", error)
  56. }
  57. return routes
  58. }
  59. function generateSitemapXML(entries: SitemapEntry[]): string {
  60. const urls = entries
  61. .map(
  62. (entry) => ` <url>
  63. <loc>${entry.url}</loc>
  64. <changefreq>${entry.changefreq}</changefreq>
  65. <priority>${entry.priority}</priority>
  66. </url>`,
  67. )
  68. .join("\n")
  69. return `<?xml version="1.0" encoding="UTF-8"?>
  70. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  71. ${urls}
  72. </urlset>`
  73. }
  74. async function main() {
  75. console.log("Generating sitemap...")
  76. const mainRoutes = await getMainRoutes()
  77. const docsRoutes = await getDocsRoutes()
  78. const allRoutes = [...mainRoutes, ...docsRoutes]
  79. console.log(`Found ${mainRoutes.length} main routes`)
  80. console.log(`Found ${docsRoutes.length} docs routes`)
  81. console.log(`Total: ${allRoutes.length} routes`)
  82. const xml = generateSitemapXML(allRoutes)
  83. const outputPath = join(PUBLIC_DIR, "sitemap.xml")
  84. await writeFile(outputPath, xml, "utf-8")
  85. console.log(`✓ Sitemap generated at ${outputPath}`)
  86. }
  87. main()