diff --git a/apps/docs/package.json b/apps/docs/package.json index eff3b0793..58302d705 100644 --- a/apps/docs/package.json +++ b/apps/docs/package.json @@ -27,6 +27,7 @@ "prettier-config": "workspace:*", "rimraf": "4.4.1", "sass": "1.62.1", + "sitemap": "7.1.1", "tsconfig": "workspace:*", "typescript": "5.0.3", "vitepress": "1.0.0-alpha.64" diff --git a/apps/docs/src/.vitepress/config.ts b/apps/docs/src/.vitepress/config.ts index bfc1ad3e1..52786c67d 100644 --- a/apps/docs/src/.vitepress/config.ts +++ b/apps/docs/src/.vitepress/config.ts @@ -1,3 +1,7 @@ +import { createWriteStream } from 'node:fs' +import { resolve } from 'node:path' +import { SitemapStream } from 'sitemap' +// import { generateSitemap } from 'sitemap-ts' import { defineConfig, type HeadConfig } from 'vitepress' import { nav, sidebar } from './menu' @@ -5,6 +9,13 @@ import { nav, sidebar } from './menu' /* Set env variable VITEPRESS_BASE to '/' for Vercel deployment previews */ const { VITEPRESS_BASE = '/nhtsa-api-wrapper/' } = process.env +interface SiteMapLink { + url: string + lastmod?: number +} + +const sitemapLinks: SiteMapLink[] = [] + export default defineConfig({ base: VITEPRESS_BASE, lang: 'en-US', @@ -44,6 +55,38 @@ export default defineConfig({ copyright: 'Copyright © 2017-present Brandon Eichler', }, }, + + // buildEnd: async () => { + // return await new Promise((resolve) => { + // return resolve( + // generateSitemap({ + // basePath: VITEPRESS_BASE, + // hostname: 'https://vpic.shaggytech.com/', + // outDir: 'src/.vitepress/dist', + // }) + // ) + // }) + // }, + + transformHtml: (_, id, { pageData }) => { + if (!/[\\/]404\.html$/.test(id)) + sitemapLinks.push({ + // you might need to change this if not using clean urls mode + url: pageData.relativePath.replace(/((^|\/)index)?\.md$/, '$2'), + lastmod: pageData.lastUpdated, + }) + }, + + buildEnd: async ({ outDir }) => { + const sitemap = new SitemapStream({ + hostname: 'https://vpic.shaggytech.com/', + }) + const writeStream = createWriteStream(resolve(outDir, 'sitemap.xml')) + sitemap.pipe(writeStream) + sitemapLinks.forEach((link) => sitemap.write(link)) + sitemap.end() + await new Promise((r) => writeStream.on('finish', r)) + }, }) function getHeadTags(): HeadConfig[] { diff --git a/apps/docs/src/public/robots.txt b/apps/docs/src/public/robots.txt index 721cc7984..90c1e48a1 100644 --- a/apps/docs/src/public/robots.txt +++ b/apps/docs/src/public/robots.txt @@ -1,3 +1,4 @@ -User-agent: * -Disallow: +User-agent: * +Allow: / + Sitemap: https://vpic.shaggytech.com/sitemap.xml \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a78c034c7..a25131dd2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -54,6 +54,9 @@ importers: sass: specifier: 1.62.1 version: 1.62.1 + sitemap: + specifier: 7.1.1 + version: 7.1.1 tsconfig: specifier: workspace:* version: link:../../config/tsconfig @@ -1221,12 +1224,22 @@ packages: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} dev: false + /@types/node@17.0.45: + resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} + dev: true + /@types/node@18.15.11: resolution: {integrity: sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==} /@types/normalize-package-data@2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} + /@types/sax@1.2.4: + resolution: {integrity: sha512-pSAff4IAxJjfAXUG6tFkO7dsSbTmf8CtUpfhhZ5VhkRpC4628tJhh3+V6H1E+/Gs9piSzYKT5yzHO5M4GG9jkw==} + dependencies: + '@types/node': 18.15.11 + dev: true + /@types/semver@6.2.3: resolution: {integrity: sha512-KQf+QAMWKMrtBMsB8/24w53tEsxllMj6TuA80TT/5igJalLI/zm0L3oXRbIAl4Ohfc85gyHX/jhMwsVkmhLU4A==} dev: false @@ -1651,6 +1664,10 @@ packages: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} dev: true + /arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + dev: true + /argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} dependencies: @@ -3928,6 +3945,10 @@ packages: source-map-js: 1.0.2 dev: true + /sax@1.2.4: + resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} + dev: true + /semver@5.7.1: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} hasBin: true @@ -4003,6 +4024,17 @@ packages: totalist: 3.0.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: true + /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'}