diff --git a/.gitignore b/.gitignore
index 705a0992c..e92a84dba 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,4 +44,7 @@ yarn-error.log*
# typescript
*.tsbuildinfo
-next-env.d.ts
\ No newline at end of file
+next-env.d.ts
+
+# misc
+/public/sitemap.xml
\ No newline at end of file
diff --git a/package.json b/package.json
index 69269919e..ec28fde12 100644
--- a/package.json
+++ b/package.json
@@ -13,10 +13,12 @@
"build-member-files": "node scripts/loadMemberFiles.js",
"local-dev": "cross-env NODE_ENV=development pnpm netlify dev",
"build": "next build",
+ "postbuild": "pnpm generate-sitemap",
"start": "next start",
"prebuild": "pnpm build-member-files",
"watch": "npm-watch",
- "dev": "pnpm build-member-files && concurrently \"pnpm watch\" \"pnpm local-dev\""
+ "dev": "pnpm build-member-files && concurrently \"pnpm watch\" \"pnpm local-dev\"",
+ "generate-sitemap": "node scripts/generate-sitemap.mjs"
},
"watch": {
"build-member-files": "src/content/members/**/*.ts"
diff --git a/scripts/generate-sitemap.mjs b/scripts/generate-sitemap.mjs
new file mode 100644
index 000000000..718ac9fa9
--- /dev/null
+++ b/scripts/generate-sitemap.mjs
@@ -0,0 +1,112 @@
+import fs from 'fs';
+import path from 'path';
+import { fileURLToPath } from 'url';
+import { getEpisodes } from '../src/data/podcast';
+import { getNewsletter } from '../src/data/newsletters';
+import { url } from 'inspector';
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
+
+async function generateStaticParams() {
+ const newsletters = await getNewsletter();
+ const podcasts = await getEpisodes();
+
+ const newsletterUrls = newsletters.map((newsletter) => ({
+ href: newsletter.href,
+ lastModified: new Date(newsletter.date),
+ }));
+ const podcastUrls = podcasts.map((podcast) => ({
+ href: podcast.href,
+ lastModified: new Date(podcast.date),
+ }));
+
+ return {
+ newsletters: newsletterUrls,
+ podcasts: podcastUrls,
+ };
+}
+
+async function sitemap() {
+ const newsletters = await generateStaticParams();
+
+ const newsletterUrls = newsletters.map((newsletter) => ({
+ url: `https://virtualcoffee.io/newsletter/issues/${newsletter.href.replace('/newsletter/issues/', '')}`,
+ lastModified: new Date(newsletter.lastModified),
+ changeFrequency: 'monthly',
+ priority: 0.7,
+ }));
+
+ return [
+ {
+ url: 'https://virtualcoffee.io',
+ lastModified: new Date(),
+ changeFrequency: 'yearly',
+ priority: 1,
+ },
+ {
+ url: 'https://virtualcoffee.io/about',
+ lastModified: new Date(),
+ changeFrequency: 'monthly',
+ priority: 0.8,
+ },
+ {
+ url: 'https://store.virtualcoffee.io/pages/contact',
+ lastModified: new Date(),
+ changeFrequency: 'yearly',
+ priority: 0.8,
+ },
+ {
+ url: 'https://virtualcoffee.io/resources',
+ lastModified: new Date(),
+ changeFrequency: 'monthly',
+ priority: 0.8,
+ },
+ {
+ url: 'https://virtualcoffee.io/resources/virtual-coffee-handbook/join-virtual-coffee',
+ lastModified: new Date(),
+ changeFrequency: 'yearly',
+ priority: 0.6,
+ },
+ {
+ url: 'https://store.virtualcoffee.io/',
+ lastModified: new Date(),
+ changeFrequency: 'monthly',
+ priority: 0.8,
+ },
+ {
+ url: 'https://store.virtualcoffee.io/collections/all',
+ lastModified: new Date(),
+ changeFrequency: 'monthly',
+ priority: 0.8,
+ },
+ ...newsletterUrls,
+ ...podcastUrls,
+ ];
+}
+
+(async () => {
+ console.log('Generating sitemap...');
+
+ const sitemapContent = (await sitemap())
+ .map(
+ (entry) => `
+
+ ${entry.url}
+ ${entry.lastModified.toISOString()}
+ ${entry.changeFrequency}
+ ${entry.priority}
+
+ `,
+ )
+ .join('');
+
+ const sitemapXml = `
+
+ ${sitemapContent}
+ `;
+
+ const outputPath = path.join(__dirname, '../public/sitemap.xml');
+ fs.writeFileSync(outputPath, sitemapXml, 'utf8');
+ console.log(`Sitemap generated successfully at ${outputPath}`);
+})();