From f85488fe2b597bd2ffaa500575582eb155f072ed Mon Sep 17 00:00:00 2001 From: Anthony GAEREMYNCK <1@anthony.sh> Date: Sun, 2 Aug 2026 16:01:21 +0200 Subject: [PATCH] feat: add sitemap generation and robots.txt --- astro.config.mjs | 12 ++++++++ package-lock.json | 67 +++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + public/robots.txt | 4 +++ tests/sitemap.test.ts | 23 +++++++++++++++ 5 files changed, 107 insertions(+) create mode 100644 public/robots.txt create mode 100644 tests/sitemap.test.ts diff --git a/astro.config.mjs b/astro.config.mjs index d097720..c61a0b6 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,4 +1,5 @@ import { defineConfig } from 'astro/config'; +import sitemap from '@astrojs/sitemap'; export default defineConfig({ site: 'https://www.ombrora.com', @@ -9,4 +10,15 @@ export default defineConfig({ prefixDefaultLocale: true, }, }, + integrations: [ + sitemap({ + i18n: { + defaultLocale: 'en', + locales: { + en: 'en', + fr: 'fr', + }, + }, + }), + ], }); diff --git a/package-lock.json b/package-lock.json index 82bef17..675d64e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "ombrora-landing", "version": "0.0.1", "dependencies": { + "@astrojs/sitemap": "^3.7.3", "astro": "^7.1.6" }, "devDependencies": { @@ -246,6 +247,17 @@ "node": ">=22.12.0" } }, + "node_modules/@astrojs/sitemap": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-3.7.3.tgz", + "integrity": "sha512-f8euLVsyeAmAkSm/1M2Kb8sL8byQmfgbvBNaHFItCheTj/IpiJYSEWVcqDHZ/yEHxiS7+w87mQkzwZaPHmk5GA==", + "license": "MIT", + "dependencies": { + "sitemap": "^9.0.0", + "stream-replace-string": "^2.0.0", + "zod": "^4.3.6" + } + }, "node_modules/@astrojs/telemetry": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.3.tgz", @@ -2022,6 +2034,24 @@ "@types/unist": "*" } }, + "node_modules/@types/node": { + "version": "24.13.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.3.tgz", + "integrity": "sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/@types/sax": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", + "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", @@ -2214,6 +2244,12 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -4007,6 +4043,25 @@ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "license": "MIT" }, + "node_modules/sitemap": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-9.0.1.tgz", + "integrity": "sha512-S6hzjGJSG3d6if0YoF5kTyeRJvia6FSTBroE5fQ0bu1QNxyJqhhinfUsXi9fH3MgtXODWvwo2BDyQSnhPQ88uQ==", + "license": "MIT", + "dependencies": { + "@types/node": "^24.9.2", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.4.1" + }, + "bin": { + "sitemap": "dist/esm/cli.js" + }, + "engines": { + "node": ">=20.19.5", + "npm": ">=10.8.2" + } + }, "node_modules/smol-toml": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.7.1.tgz", @@ -4052,6 +4107,12 @@ "dev": true, "license": "MIT" }, + "node_modules/stream-replace-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stream-replace-string/-/stream-replace-string-2.0.0.tgz", + "integrity": "sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==", + "license": "MIT" + }, "node_modules/stringify-entities": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", @@ -4193,6 +4254,12 @@ "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", "license": "MIT" }, + "node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "license": "MIT" + }, "node_modules/unified": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", diff --git a/package.json b/package.json index c2774d1..aadf322 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "test": "vitest run" }, "dependencies": { + "@astrojs/sitemap": "^3.7.3", "astro": "^7.1.6" }, "devDependencies": { diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..989ba86 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / + +Sitemap: https://www.ombrora.com/sitemap-index.xml diff --git a/tests/sitemap.test.ts b/tests/sitemap.test.ts new file mode 100644 index 0000000..76bb651 --- /dev/null +++ b/tests/sitemap.test.ts @@ -0,0 +1,23 @@ +import { describe, it, expect, beforeAll } from 'vitest'; +import { execSync } from 'node:child_process'; +import { readFileSync, existsSync } from 'node:fs'; + +describe('sitemap and robots.txt', () => { + beforeAll(() => { + execSync('npm run build', { stdio: 'inherit' }); + }); + + it('generates a sitemap index referencing both locales', () => { + expect(existsSync('dist/sitemap-index.xml')).toBe(true); + const sitemap = readFileSync('dist/sitemap-0.xml', 'utf-8'); + expect(sitemap).toContain('https://www.ombrora.com/en/'); + expect(sitemap).toContain('https://www.ombrora.com/fr/'); + }); + + it('robots.txt allows all crawlers and points to the sitemap', () => { + const robots = readFileSync('dist/robots.txt', 'utf-8'); + expect(robots).toContain('User-agent: *'); + expect(robots).toContain('Allow: /'); + expect(robots).toContain('Sitemap: https://www.ombrora.com/sitemap-index.xml'); + }); +});