Skip to content

Commit

Permalink
feat(sitemap): support SSR generated routes
Browse files Browse the repository at this point in the history
  • Loading branch information
atilafassina committed Mar 13, 2023
1 parent 875a04d commit 1b73cea
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 11 deletions.
1 change: 1 addition & 0 deletions packages/integrations/sitemap/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"test": "mocha --timeout 20000"
},
"dependencies": {
"fast-glob": "^3.2.11",
"sitemap": "^7.1.1",
"zod": "^3.17.3"
},
Expand Down
71 changes: 60 additions & 11 deletions packages/integrations/sitemap/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ import {
simpleSitemapAndIndex,
SitemapItemLoose,
} from 'sitemap';
import { resolve } from 'path';
import { fileURLToPath } from 'url';
import fg from 'fast-glob';
import { ZodError } from 'zod';

import { generateSitemap } from './generate-sitemap.js';
import { Logger } from './utils/logger.js';
import { isRoutePrerendered } from './utils/is-route-prerendered.js';
import { validateOptions } from './validate-options.js';

export type ChangeFreq = `${EnumChangefreq}`;
Expand Down Expand Up @@ -51,18 +54,71 @@ const OUTFILE = 'sitemap-index.xml';

const createPlugin = (options?: SitemapOptions): AstroIntegration => {
let config: AstroConfig;
const logger = new Logger(PKG_NAME);

return {
name: PKG_NAME,

hooks: {
'astro:config:done': async ({ config: cfg }) => {
config = cfg;
if (cfg.site) {
config = cfg;
} else {
// eslint-disable-next-line no-console
console.warn(
'The Sitemap integration requires the `site` astro.config option. Skipping.'
);
return;
}
},

'astro:build:done': async ({ dir, pages }) => {
const logger = new Logger(PKG_NAME);
'astro:build:start': async () => {
if (config.output !== 'server' || !config.site) {
return;
}

const srcPath = fileURLToPath(config.srcDir);
const pagesPath = resolve(srcPath, 'pages');

const pageFiles = await fg(`${pagesPath}/**/*.{astro,ts,js}`);

const routes = (
await Promise.all(
pageFiles.map(async (filePath) => {
const isPrerendered = await isRoutePrerendered(filePath);
const index = filePath.indexOf('pages/') + 6;
const routeSegment = filePath
.substring(index)
.replace(/\.(astro|ts|js)/, '')
.replace(/index$/, '');

/**
* @TODO
* figure out how to run `getStaticPaths` here.
*/
const isDynamicRoute = routeSegment.endsWith(']');
const shouldIndex = !isDynamicRoute && !isPrerendered;

return shouldIndex ? `${config.site}/${routeSegment}` : undefined;
})
)
).filter((route): route is string => Boolean(route));
const opts = validateOptions(config.site, options);

opts.customPages = opts.customPages
? Array.from(new Set([...routes, ...opts.customPages]))
: routes;
options = opts;

logger.info(`build is starting + ${JSON.stringify(opts.customPages, null, 2)}`);
},

'astro:build:done': async ({ dir, pages }) => {
try {
if (!config.site) {
return;
}

const opts = validateOptions(config.site, options);

const { filter, customPages, serialize, entryLimit } = opts;
Expand Down Expand Up @@ -97,14 +153,7 @@ const createPlugin = (options?: SitemapOptions): AstroIntegration => {
}

if (pageUrls.length === 0) {
// offer suggestion for SSR users
if (config.output !== 'static') {
logger.warn(
`No pages found! We can only detect sitemap routes for "static" builds. Since you are using an SSR adapter, we recommend manually listing your sitemap routes using the "customPages" integration option.\n\nExample: \`sitemap({ customPages: ['https://example.com/route'] })\``
);
} else {
logger.warn(`No pages found!\n\`${OUTFILE}\` not created.`);
}
logger.warn(`No pages found!\n\`${OUTFILE}\` not created.`);
return;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const REGEX_PRERENDER = /const prerender = true/g;
import { readFile } from 'fs/promises';

export async function isRoutePrerendered(filePath: string) {
const contents = await readFile(filePath, 'utf-8');

return REGEX_PRERENDER.test(contents);
}
2 changes: 2 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 1b73cea

Please sign in to comment.