summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--package-lock.json44
-rw-r--r--package.json4
-rw-r--r--scripts/generate-sitemap.ts36
-rw-r--r--static/robots.txt1
-rw-r--r--static/sitemap.txt6
5 files changed, 90 insertions, 1 deletions
diff --git a/package-lock.json b/package-lock.json
index 1606b4a..f1b44c0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -23,6 +23,7 @@
"mdsvex": "^0.12.6",
"svelte": "^5.48.2",
"svelte-check": "^4.3.5",
+ "tsx": "^4.21.0",
"typescript": "^5.9.3",
"typescript-eslint": "^8.53.1",
"vite": "^7.3.1"
@@ -2340,6 +2341,19 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
+ "node_modules/get-tsconfig": {
+ "version": "4.13.6",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz",
+ "integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
"node_modules/glob-parent": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -3235,6 +3249,16 @@
"node": ">=4"
}
},
+ "node_modules/resolve-pkg-maps": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+ }
+ },
"node_modules/rollup": {
"version": "4.57.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.57.0.tgz",
@@ -3558,6 +3582,26 @@
"typescript": ">=4.8.4"
}
},
+ "node_modules/tsx": {
+ "version": "4.21.0",
+ "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz",
+ "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "~0.27.0",
+ "get-tsconfig": "^4.7.5"
+ },
+ "bin": {
+ "tsx": "dist/cli.mjs"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ }
+ },
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
diff --git a/package.json b/package.json
index 8fb400b..c860808 100644
--- a/package.json
+++ b/package.json
@@ -5,7 +5,8 @@
"type": "module",
"scripts": {
"dev": "vite dev",
- "build": "vite build",
+ "generate:sitemap": "tsx scripts/generate-sitemap.ts",
+ "build": "npm run generate:sitemap && vite build",
"preview": "vite preview",
"prepare": "svelte-kit sync || echo ''",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
@@ -25,6 +26,7 @@
"mdsvex": "^0.12.6",
"svelte": "^5.48.2",
"svelte-check": "^4.3.5",
+ "tsx": "^4.21.0",
"typescript": "^5.9.3",
"typescript-eslint": "^8.53.1",
"vite": "^7.3.1"
diff --git a/scripts/generate-sitemap.ts b/scripts/generate-sitemap.ts
new file mode 100644
index 0000000..e521365
--- /dev/null
+++ b/scripts/generate-sitemap.ts
@@ -0,0 +1,36 @@
+import { promises as fs } from 'node:fs';
+import path from 'node:path';
+import { fileURLToPath } from 'node:url';
+
+const SITE_URL = (process.env.SITE_URL ?? 'https://wsap.dev').replace(/\/+$/, '');
+const STATIC_ROUTES = ['/', '/about', '/apps'];
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
+const projectRoot = path.resolve(__dirname, '..');
+const postsDir = path.join(projectRoot, 'src', 'posts');
+const sitemapPath = path.join(projectRoot, 'static', 'sitemap.txt');
+
+async function getPostRoutes(): Promise<string[]> {
+ const files = await fs.readdir(postsDir);
+
+ return files
+ .filter((file) => file.endsWith('.svx'))
+ .map((file) => `/posts/${file.replace(/\.svx$/, '')}`)
+ .sort();
+}
+
+async function main(): Promise<void> {
+ const postRoutes = await getPostRoutes();
+ const urls = [...STATIC_ROUTES, ...postRoutes].map((route) => `${SITE_URL}${route}`);
+ const body = `${urls.join('\n')}\n`;
+
+ await fs.writeFile(sitemapPath, body, 'utf8');
+ console.log(`Generated sitemap: ${path.relative(projectRoot, sitemapPath)} (${urls.length} URLs)`);
+}
+
+main().catch((error: unknown) => {
+ console.error('Failed to generate sitemap.txt');
+ console.error(error);
+ process.exit(1);
+});
diff --git a/static/robots.txt b/static/robots.txt
index b6dd667..32937f0 100644
--- a/static/robots.txt
+++ b/static/robots.txt
@@ -1,3 +1,4 @@
# allow crawling everything by default
User-agent: *
Disallow:
+Sitemap: https://wsap.dev/sitemap.txt
diff --git a/static/sitemap.txt b/static/sitemap.txt
new file mode 100644
index 0000000..1e44ce9
--- /dev/null
+++ b/static/sitemap.txt
@@ -0,0 +1,6 @@
+https://wsap.dev/
+https://wsap.dev/about
+https://wsap.dev/apps
+https://wsap.dev/posts/first-post
+https://wsap.dev/posts/modafinil-and-me
+https://wsap.dev/posts/you-dont-need-mediainfo