64 lines
2.5 KiB
JavaScript
64 lines
2.5 KiB
JavaScript
/**
|
|
* Generate sitemap.xml for TailTrails.
|
|
* Run: node scripts/generate-sitemap.mjs
|
|
* Output: public/sitemap.xml (copied to dist/ by the subsequent vite build)
|
|
*
|
|
* Blog slugs are auto-discovered from src/blogs/posts/*.tsx so the sitemap
|
|
* can't drift from the actual posts.
|
|
*/
|
|
import fs from "fs";
|
|
import path from "path";
|
|
import { fileURLToPath } from "url";
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const SITE_URL = "https://tailtrails.club";
|
|
const POSTS_DIR = path.resolve(__dirname, "..", "src", "blogs", "posts");
|
|
const TODAY = new Date().toISOString().split("T")[0];
|
|
|
|
const staticRoutes = [
|
|
{ path: "/", priority: "1.0", changefreq: "weekly" },
|
|
{ path: "/blog", priority: "0.9", changefreq: "weekly" },
|
|
{ path: "/compare", priority: "0.9", changefreq: "weekly" },
|
|
{ path: "/compare/dog-walking-apps-compared", priority: "0.8", changefreq: "monthly" },
|
|
{ path: "/compare/tailtrails-vs-wooftrax", priority: "0.7", changefreq: "monthly" },
|
|
{ path: "/compare/tailtrails-vs-tractive", priority: "0.7", changefreq: "monthly" },
|
|
{ path: "/compare/tailtrails-vs-alltrails", priority: "0.7", changefreq: "monthly" },
|
|
{ path: "/compare/tailtrails-vs-fitbark", priority: "0.7", changefreq: "monthly" },
|
|
{ path: "/compare/tailtrails-vs-pitpat", priority: "0.7", changefreq: "monthly" },
|
|
{ path: "/privacy", priority: "0.3", changefreq: "yearly" },
|
|
{ path: "/terms", priority: "0.3", changefreq: "yearly" },
|
|
{ path: "/forget-me", priority: "0.3", changefreq: "yearly" },
|
|
{ path: "/finalize-forget-me", priority: "0.3", changefreq: "yearly" },
|
|
// /download is a redirect stub — not indexed, omitted from sitemap.
|
|
];
|
|
|
|
const blogSlugs = fs.existsSync(POSTS_DIR)
|
|
? fs.readdirSync(POSTS_DIR).filter((f) => f.endsWith(".tsx")).map((f) => f.replace(/\.tsx$/, ""))
|
|
: [];
|
|
const blogRoutes = blogSlugs.map((slug) => ({
|
|
path: `/blog/${slug}`,
|
|
priority: "0.7",
|
|
changefreq: "monthly",
|
|
}));
|
|
|
|
const allRoutes = [...staticRoutes, ...blogRoutes];
|
|
|
|
const xmlUrls = allRoutes
|
|
.map(
|
|
(r) => ` <url>
|
|
<loc>${SITE_URL}${r.path}</loc>
|
|
<lastmod>${TODAY}</lastmod>
|
|
<changefreq>${r.changefreq}</changefreq>
|
|
<priority>${r.priority}</priority>
|
|
</url>`
|
|
)
|
|
.join("\n");
|
|
|
|
const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
|
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
${xmlUrls}
|
|
</urlset>`;
|
|
|
|
const outputPath = path.join(__dirname, "..", "public", "sitemap.xml");
|
|
fs.writeFileSync(outputPath, sitemap, "utf8");
|
|
console.log(`✅ Sitemap generated: ${outputPath} (${allRoutes.length} URLs)`); |