diff --git a/app/sitemap.js b/app/sitemap.js new file mode 100644 index 0000000..733e589 --- /dev/null +++ b/app/sitemap.js @@ -0,0 +1,11 @@ +import { createReadStream } from 'fs'; +import { ServerResponse } from 'http'; + +const sitemapHandler = async (_, res = ServerResponse) => { + const sitemap = createReadStream('./public/sitemap.xml.gz'); + res.setHeader('content-type', 'application/xml'); + res.setHeader('content-encoding', 'gzip'); + sitemap.pipe(res); +}; + +export default sitemapHandler; diff --git a/generate-sitemap.js b/generate-sitemap.js new file mode 100644 index 0000000..b562b76 --- /dev/null +++ b/generate-sitemap.js @@ -0,0 +1,25 @@ +// sitemap-generator.js +const { SitemapStream, streamToPromise } = require("sitemap"); +const { createGzip } = require("zlib"); +const fs = require("fs"); + +async function generateSitemap() { + const sitemap = new SitemapStream({ + hostname: "https://alvalens.my.id/", + }); + + // Add URLs to your sitemap + sitemap.write({ url: "/", changefreq: "daily", priority: 1.0 }); + sitemap.write({ url: "/about", changefreq: "daily", priority: 0.9 }); + sitemap.write({ url: "/projects", changefreq: "daily", priority: 0.9 }); + sitemap.write({ url: "/projects/archive", changefreq: "daily", priority: 0.9 }); + + sitemap.end(); + + const sitemapXML = (await streamToPromise(sitemap)).toString(); + const gzippedSitemap = createGzip(); + + fs.writeFileSync("./public/sitemap.xml.gz", sitemapXML); +} + +generateSitemap(); diff --git a/package.json b/package.json index ff8e255..2af3d5a 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "dev": "next dev --turbo", "build": "next build", "start": "next start", - "lint": "next lint" + "lint": "next lint", + "generate-sitemap": "node generate-sitemap.js" }, "dependencies": { "@fortawesome/fontawesome-svg-core": "^6.4.2", @@ -24,6 +25,7 @@ "postcss": "8.4.28", "react": "18.2.0", "react-dom": "18.2.0", + "sitemap": "^7.1.1", "swr": "^2.2.2", "tailwindcss": "3.3.3" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6e90076..ffeefc9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -50,6 +50,9 @@ dependencies: react-dom: specifier: 18.2.0 version: 18.2.0(react@18.2.0) + sitemap: + specifier: ^7.1.1 + version: 7.1.1 swr: specifier: ^2.2.2 version: 2.2.2(react@18.2.0) @@ -388,6 +391,16 @@ packages: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: false + /@types/node@17.0.45: + resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} + dev: false + + /@types/sax@1.2.4: + resolution: {integrity: sha512-pSAff4IAxJjfAXUG6tFkO7dsSbTmf8CtUpfhhZ5VhkRpC4628tJhh3+V6H1E+/Gs9piSzYKT5yzHO5M4GG9jkw==} + dependencies: + '@types/node': 17.0.45 + dev: false + /@typescript-eslint/parser@6.5.0(eslint@8.48.0)(typescript@5.2.2): resolution: {integrity: sha512-LMAVtR5GN8nY0G0BadkG0XIe4AcNMeyEy3DyhKGAh9k4pLSMBO7rF29JvDBpZGCmp5Pgz5RLHP6eCpSYZJQDuQ==} engines: {node: ^16.0.0 || >=18.0.0} @@ -2342,6 +2355,10 @@ packages: is-regex: 1.1.4 dev: false + /sax@1.2.4: + resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} + dev: false + /scheduler@0.23.0: resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} dependencies: @@ -2388,6 +2405,17 @@ packages: totalist: 1.1.0 dev: true + /sitemap@7.1.1: + resolution: {integrity: sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==} + engines: {node: '>=12.0.0', npm: '>=5.6.0'} + hasBin: true + dependencies: + '@types/node': 17.0.45 + '@types/sax': 1.2.4 + arg: 5.0.2 + sax: 1.2.4 + dev: false + /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} diff --git a/public/sitemap.xml.gz b/public/sitemap.xml.gz new file mode 100644 index 0000000..2c2591a --- /dev/null +++ b/public/sitemap.xml.gz @@ -0,0 +1 @@ +https://alvalens.my.id/daily1.0https://alvalens.my.id/aboutdaily0.9https://alvalens.my.id/projectsdaily0.9https://alvalens.my.id/projects/archivedaily0.9 \ No newline at end of file