diff --git a/src/module.ts b/src/module.ts index 6f50b15e5..9efaba9ea 100644 --- a/src/module.ts +++ b/src/module.ts @@ -173,13 +173,16 @@ export default defineNuxtModule({ // Prerender database.sql routes for each collection to fetch dump nuxt.options.routeRules ||= {} - // @ts-expect-error - Prevent nuxtseo from indexing nuxt-content routes - // @see https://github.com/nuxt/content/pull/3299 - nuxt.options.routeRules![`/__nuxt_content/**`] = { robots: false } + nuxt.options.routeRules![`/__nuxt_content/**`] = { + ...nuxt.options.routeRules![`/__nuxt_content/**`], + // @ts-expect-error - Prevent nuxtseo from indexing nuxt-content routes + robots: false, + } manifest.collections.forEach((collection) => { if (!collection.private) { - nuxt.options.routeRules![`/__nuxt_content/${collection.name}/sql_dump.txt`] = { prerender: true } + const key = `/__nuxt_content/${collection.name}/sql_dump.txt` + nuxt.options.routeRules![key] = { ...nuxt.options.routeRules![key], prerender: true } } }) @@ -217,7 +220,7 @@ export default defineNuxtModule({ nuxt.hook('modules:done', async () => { const preset = findPreset(nuxt) - await preset?.setup?.(options, nuxt) + await preset?.setup?.(options, nuxt, { resolver, manifest }) // Provide default database configuration here since nuxt is merging defaults and user options options.database ||= { type: 'sqlite', filename: './contents.sqlite' } await refineDatabaseConfig(options._localDatabase, { rootDir: nuxt.options.rootDir, updateSqliteFileName: true }) diff --git a/src/presets/cloudflare.ts b/src/presets/cloudflare.ts index beb43bb2a..501b30ba3 100644 --- a/src/presets/cloudflare.ts +++ b/src/presets/cloudflare.ts @@ -1,4 +1,4 @@ -import { addTemplate } from '@nuxt/kit' +import { addServerHandler, addTemplate } from '@nuxt/kit' import { join } from 'pathe' import { logger } from '../utils/dev' import { definePreset } from '../utils/preset' @@ -6,7 +6,15 @@ import { collectionDumpTemplate } from '../utils/templates' export default definePreset({ name: 'cloudflare', - async setupNitro(nitroConfig, { manifest, resolver }) { + setup(_options, _nuxt, { resolver, manifest }) { + manifest.collections.map(async (collection) => { + addServerHandler({ + route: `/__nuxt_content/${collection.name}/sql_dump.txt`, + handler: resolver.resolve('./runtime/presets/cloudflare/database-handler'), + }) + }) + }, + async setupNitro(nitroConfig, { manifest }) { if (nitroConfig.runtimeConfig?.content?.database?.type === 'sqlite') { logger.warn('Deploying to Cloudflare requires using D1 database, switching to D1 database with binding `DB`.') nitroConfig.runtimeConfig!.content!.database = { type: 'd1', bindingName: 'DB' } @@ -25,10 +33,6 @@ export default definePreset({ // Add raw content dump to public assets nitroConfig.publicAssets.push({ dir: join(nitroConfig.buildDir!, 'content', 'raw'), maxAge: 60 }) - nitroConfig.handlers.push({ - route: '/__nuxt_content/:collection/sql_dump.txt', - handler: resolver.resolve('./runtime/presets/cloudflare/database-handler'), - }) }, }) diff --git a/src/presets/node.ts b/src/presets/node.ts index 6e4a15d09..4b4bb3405 100644 --- a/src/presets/node.ts +++ b/src/presets/node.ts @@ -1,18 +1,25 @@ -import { addTemplate } from '@nuxt/kit' +import { addServerHandler, addTemplate } from '@nuxt/kit' import { fullDatabaseCompressedDumpTemplate } from '../utils/templates' import { definePreset } from '../utils/preset' export default definePreset({ name: 'node', - setupNitro(nitroConfig, { manifest, resolver }) { + setup(_options, _nuxt, { resolver, manifest }) { + // Due to prerender enabling in the module, Nuxt create a route for each collection + // These routes cause issue while enabling cache in Nuxt. + // So we need to add a server handler for each collection to handle the request. + manifest.collections.map(async (collection) => { + addServerHandler({ + route: `/__nuxt_content/${collection.name}/sql_dump.txt`, + handler: resolver.resolve('./runtime/presets/node/database-handler'), + }) + }) + }, + setupNitro(nitroConfig, { manifest }) { nitroConfig.publicAssets ||= [] nitroConfig.alias = nitroConfig.alias || {} nitroConfig.handlers ||= [] nitroConfig.alias['#content/dump'] = addTemplate(fullDatabaseCompressedDumpTemplate(manifest)).dst - nitroConfig.handlers.push({ - route: '/__nuxt_content/:collection/sql_dump.txt', - handler: resolver.resolve('./runtime/presets/node/database-handler'), - }) }, }) diff --git a/src/runtime/presets/cloudflare/database-handler.ts b/src/runtime/presets/cloudflare/database-handler.ts index 93c9eb445..b19c091e0 100644 --- a/src/runtime/presets/cloudflare/database-handler.ts +++ b/src/runtime/presets/cloudflare/database-handler.ts @@ -2,7 +2,7 @@ import { eventHandler, getRouterParam, setHeader } from 'h3' import { useStorage } from 'nitropack/runtime' export default eventHandler(async (event) => { - const collection = getRouterParam(event, 'collection')! + const collection = getRouterParam(event, 'collection')! || event.path?.split('/')?.[2] || '' setHeader(event, 'Content-Type', 'text/plain') const ASSETS = event?.context?.cloudflare?.env.ASSETS || process.env.ASSETS diff --git a/src/runtime/presets/node/database-handler.ts b/src/runtime/presets/node/database-handler.ts index 2df88eeb9..e5e32695a 100644 --- a/src/runtime/presets/node/database-handler.ts +++ b/src/runtime/presets/node/database-handler.ts @@ -2,7 +2,7 @@ import { eventHandler, getRouterParam, setHeader } from 'h3' import { useStorage } from 'nitropack/runtime' export default eventHandler(async (event) => { - const collection = getRouterParam(event, 'collection')! + const collection = getRouterParam(event, 'collection')! || event.path?.split('/')?.[2] || '' setHeader(event, 'Content-Type', 'text/plain') const data = await useStorage().getItem(`build:content:database.compressed.mjs`) || '' diff --git a/src/utils/preset.ts b/src/utils/preset.ts index 7b2a6cc76..99ef6a6d5 100644 --- a/src/utils/preset.ts +++ b/src/utils/preset.ts @@ -13,18 +13,18 @@ interface Options { export interface Preset { name: string parent?: Preset - setup?: (options: ModuleOptions, nuxt: Nuxt) => Promise | void + setup?: (options: ModuleOptions, nuxt: Nuxt, opts: { resolver: Resolver, manifest: Manifest }) => Promise | void setupNitro: (nitroConfig: NitroConfig, opts: Options) => void | Promise } export function definePreset(preset: Preset) { const _preset: Preset = { ...preset, - setup: async (options, nuxt) => { + setup: async (options, nuxt, opts) => { if (preset.parent) { - await preset.parent.setup?.(options, nuxt) + await preset.parent.setup?.(options, nuxt, opts) } - await preset.setup?.(options, nuxt) + await preset.setup?.(options, nuxt, opts) }, setupNitro: async (nitroConfig, opts) => { if (preset.parent) {