Load details via by-id, build links from pathSlug/title, redirect legacy slug URLs, and update the sitemap template. Co-authored-by: Cursor <cursoragent@cursor.com>
112 lines
3.0 KiB
JavaScript
112 lines
3.0 KiB
JavaScript
/**
|
|
* Scans app page routes and writes src/lib/sitemap-config.generated.json
|
|
* for GET /meshkee/sitemap-config.json (Meshkee sitemap sync).
|
|
*/
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
const appDir = path.join(root, "src", "app");
|
|
const outFile = path.join(root, "src", "lib", "sitemap-config.generated.json");
|
|
|
|
const EXCLUDE_SEGMENTS = new Set([
|
|
"api",
|
|
"meshkee",
|
|
"admin",
|
|
"auth",
|
|
"login",
|
|
"checkout",
|
|
"cart",
|
|
"account",
|
|
]);
|
|
|
|
const PRIORITY = {
|
|
"/": { changefreq: "daily", priority: 1.0 },
|
|
"/user-products": { changefreq: "daily", priority: 0.9 },
|
|
"/categories": { changefreq: "weekly", priority: 0.8 },
|
|
"/blog": { changefreq: "weekly", priority: 0.8 },
|
|
"/about": { changefreq: "monthly", priority: 0.6 },
|
|
"/contact": { changefreq: "monthly", priority: 0.5 },
|
|
};
|
|
|
|
function websiteDomain() {
|
|
return (
|
|
process.env.NEXT_PUBLIC_SITE_DOMAIN ||
|
|
process.env.NEXT_PUBLIC_WEBSITE_DOMAIN ||
|
|
process.env.WEBSITE_DOMAIN ||
|
|
"www.mashinify.com"
|
|
);
|
|
}
|
|
|
|
function walkPages(dir, segments = []) {
|
|
/** @type {string[]} */
|
|
const pages = [];
|
|
if (!fs.existsSync(dir)) return pages;
|
|
|
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
const full = path.join(dir, entry.name);
|
|
|
|
if (entry.isDirectory()) {
|
|
if (EXCLUDE_SEGMENTS.has(entry.name)) continue;
|
|
if (/^\[.+\]$/.test(entry.name) || /^\(.+\)$/.test(entry.name)) {
|
|
if (/^\(.+\)$/.test(entry.name)) {
|
|
pages.push(...walkPages(full, segments));
|
|
}
|
|
continue;
|
|
}
|
|
pages.push(...walkPages(full, [...segments, entry.name]));
|
|
continue;
|
|
}
|
|
|
|
if (
|
|
entry.name === "page.tsx" ||
|
|
entry.name === "page.ts" ||
|
|
entry.name === "page.jsx" ||
|
|
entry.name === "page.js"
|
|
) {
|
|
const routePath = segments.length ? `/${segments.join("/")}` : "/";
|
|
pages.push(routePath);
|
|
}
|
|
}
|
|
|
|
return pages;
|
|
}
|
|
|
|
function main() {
|
|
const paths = [...new Set(walkPages(appDir))].sort((a, b) => {
|
|
if (a === "/") return -1;
|
|
if (b === "/") return 1;
|
|
return a.localeCompare(b);
|
|
});
|
|
|
|
const staticPages = paths.map((routePath) => {
|
|
const meta = PRIORITY[routePath] ?? {
|
|
changefreq: "monthly",
|
|
priority: 0.5,
|
|
};
|
|
return { path: routePath, ...meta };
|
|
});
|
|
|
|
const domain = websiteDomain().replace(/^https?:\/\//, "").replace(/\/+$/, "");
|
|
|
|
const config = {
|
|
baseUrl: `https://${domain}`,
|
|
staticPages,
|
|
// Mashinify public paths differ from Meshkee catalog defaults.
|
|
templates: {
|
|
userProduct: "/user-products/{id}/{slug}",
|
|
blog: "/blog/{slug}",
|
|
},
|
|
};
|
|
|
|
fs.mkdirSync(path.dirname(outFile), { recursive: true });
|
|
fs.writeFileSync(outFile, `${JSON.stringify(config, null, 2)}\n`, "utf8");
|
|
console.log(
|
|
`Wrote ${path.relative(root, outFile)} (${staticPages.length} static pages)`,
|
|
);
|
|
}
|
|
|
|
main();
|