diff --git a/modules/isr-fallback.ts b/modules/isr-fallback.ts index 13a7f92fe..097bfe467 100644 --- a/modules/isr-fallback.ts +++ b/modules/isr-fallback.ts @@ -13,6 +13,8 @@ export default defineNuxtModule({ } nuxt.hook('nitro:init', nitro => { + const htmlFallback = 'spa.prerender-fallback.html' + const jsonFallback = 'payload-fallback.json' nitro.hooks.hook('compiled', () => { const spaTemplate = readFileSync(nitro.options.output.publicDir + '/200.html', 'utf-8') for (const path of [ @@ -26,14 +28,10 @@ export default defineNuxtModule({ 'package/[org]/[name]/v/[version]', '', ]) { - const outputPath = resolve( - nitro.options.output.serverDir, - '..', - path, - 'spa.prerender-fallback.html', - ) + const outputPath = resolve(nitro.options.output.serverDir, '..', path, htmlFallback) mkdirSync(resolve(nitro.options.output.serverDir, '..', path), { recursive: true }) writeFileSync(outputPath, spaTemplate) + writeFileSync(outputPath.replace(htmlFallback, jsonFallback), '{}') } }) }) diff --git a/nuxt.config.ts b/nuxt.config.ts index 935334cbd..39d4bbb4f 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -108,7 +108,7 @@ export default defineNuxtConfig({ '/api/registry/package-meta/**': { isr: 300 }, '/:pkg/.well-known/skills/**': { isr: 3600 }, '/:scope/:pkg/.well-known/skills/**': { isr: 3600 }, - '/__og-image__/**': { isr: getISRConfig(60) }, + '/__og-image__/**': getISRConfig(60), '/_avatar/**': { isr: 3600, proxy: 'https://www.gravatar.com/avatar/**' }, '/opensearch.xml': { isr: true }, '/oauth-client-metadata.json': { prerender: true }, @@ -123,10 +123,14 @@ export default defineNuxtConfig({ }, }, // pages - '/package/:name': { isr: getISRConfig(60, true) }, - '/package/:name/v/:version': { isr: getISRConfig(60, true) }, - '/package/:org/:name': { isr: getISRConfig(60, true) }, - '/package/:org/:name/v/:version': { isr: getISRConfig(60, true) }, + '/package/:name': getISRConfig(60, { fallback: 'html' }), + '/package/:name/_payload.json': getISRConfig(60, { fallback: 'json' }), + '/package/:name/v/:version': getISRConfig(60, { fallback: 'html' }), + '/package/:name/v/:version/_payload.json': getISRConfig(60, { fallback: 'json' }), + '/package/:org/:name': getISRConfig(60, { fallback: 'html' }), + '/package/:org/:name/_payload.json': getISRConfig(60, { fallback: 'json' }), + '/package/:org/:name/v/:version': getISRConfig(60, { fallback: 'html' }), + '/package/:org/:name/v/:version/_payload.json': getISRConfig(60, { fallback: 'json' }), // infinite cache (versioned - doesn't change) '/package-code/**': { isr: true, cache: { maxAge: 365 * 24 * 60 * 60 } }, '/package-docs/**': { isr: true, cache: { maxAge: 365 * 24 * 60 * 60 } }, @@ -314,14 +318,23 @@ export default defineNuxtConfig({ }, }) -function getISRConfig(expirationSeconds: number, fallback = false) { - if (fallback) { +interface ISRConfigOptions { + fallback?: 'html' | 'json' +} +function getISRConfig(expirationSeconds: number, options: ISRConfigOptions = {}) { + if (options.fallback) { return { - expiration: expirationSeconds, - fallback: 'spa.prerender-fallback.html', - } as { expiration: number } + isr: { + expiration: expirationSeconds, + fallback: + options.fallback === 'html' ? 'spa.prerender-fallback.html' : 'payload-fallback.json', + initialHeaders: options.fallback === 'json' ? { 'content-type': 'application/json' } : {}, + } as { expiration: number }, + } } return { - expiration: expirationSeconds, + isr: { + expiration: expirationSeconds, + }, } }