Files
3031023-xyz-public/scripts/generate-seo.mjs
T

29 lines
1.8 KiB
JavaScript

import { readdir, readFile, writeFile } from 'node:fs/promises';
import { join, relative, sep } from 'node:path';
const key = process.env.SITE_KEY;
if (!key) throw new Error('SITE_KEY is required.');
const manifest = JSON.parse(await readFile('sites.json', 'utf8'));
const deployment = manifest.sites[key];
if (!deployment) throw new Error(`Unknown site key: ${key}`);
const outputDir = `dist/${key}`;
async function htmlFiles(dir) {
const entries = await readdir(dir, { withFileTypes: true });
const nested = await Promise.all(entries.map(async (entry) => entry.isDirectory() ? htmlFiles(join(dir, entry.name)) : entry.name.endsWith('.html') ? [join(dir, entry.name)] : []));
return nested.flat();
}
const urls = (await Promise.all((await htmlFiles(outputDir)).map(async (file) => {
const html = await readFile(file, 'utf8');
if (/<title>Redirecting to:/i.test(html)) return null;
const path = relative(outputDir, file).split(sep).join('/');
if (path === '404.html') return null;
return path === 'index.html' ? '/' : `/${path.replace(/index\.html$/, '')}`;
}))).filter(Boolean).sort();
const origin = `https://${deployment.hostname}`;
const sitemap = `<?xml version="1.0" encoding="UTF-8"?>\n<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n${urls.map((path) => ` <url><loc>${origin}${path}</loc></url>`).join('\n')}\n</urlset>\n`;
const robots = process.env.DEPLOY_ENV === 'production' ? `User-agent: *\nAllow: /\nSitemap: ${origin}/sitemap.xml\n` : 'User-agent: *\nDisallow: /\n';
await Promise.all([writeFile(join(outputDir, 'sitemap.xml'), sitemap), writeFile(join(outputDir, 'robots.txt'), robots)]);
console.log(`Generated ${urls.length} sitemap URLs and ${process.env.DEPLOY_ENV === 'production' ? 'production' : 'preview'} robots rules for ${key}.`);