-
-
Notifications
You must be signed in to change notification settings - Fork 745
[Cloudflare preset] Per-collection sql_dump.txt prerender serves stale content #3730
Description
Environment
| Operating system | macOS 24.5.0 |
| CPU | Apple M2 Pro (10 cores) |
| Node.js version | v24.11.1 |
| nuxt/cli version | 3.33.1 |
| Package manager | pnpm@10.4.1 |
| Nuxt version | 4.3.1 |
| Nitro version | 2.13.1 |
| Builder | vite@7.3.1 |
| Config | app, colorMode, compatibilityDate, css, modules, nitro, site, ssr, vite |
| Modules | @nuxt/ui@4.4.0, @nuxt/content@3.11.2, @nuxtjs/sitemap@7.6.0 |
Version
v3.11.2
Reproduction
Not feasible as a minimal repo — requires Cloudflare Pages deployment with D1 binding
Description
When deploying to Cloudflare Pages with ssr: false, content changes are
not reflected in the prerendered
/__nuxt_content/{collection}/sql_dump.txt files. The build correctly
parses markdown files (0 cached, 19 parsed) and
.data/content/contents.sqlite contains the updated content, but the
prerendered dump files serve stale data.
This was discovered while debugging a deployment issue where docs content
wouldn't update on Cloudflare Pages despite fresh builds and cache
purges. After hours of debugging, Claude Code (Anthropic's AI coding
agent) traced the issue through the build pipeline and identified the
root cause in the module source. I'm not deeply familiar with the
@nuxt/content internals to fully verify the analysis, but applying the
suggested workaround (copying the correct root-level dump files over the
prerendered ones) did fix the deployment and the live site now serves the
updated content.
Root cause (as identified by Claude Code):
In module.mjs, the Cloudflare preset registers per-collection dump
templates via collectionDumpTemplate() inside setupNitro:
manifest.collections.map(async (collection) => {
if (!collection.private) {
addTemplate(collectionDumpTemplate(collection.name, manifest));
}
});
However, the updateTemplates() call in the modules:done hook only
refreshes:
await updateTemplates({
filter: (template) => [
moduleTemplates.fullRawDump,
moduleTemplates.fullCompressedDump,
moduleTemplates.manifest,
moduleTemplates.components
].includes(template.filename)
});
The per-collection templates (content/raw/dump.{collection}.sql) are not
included in the filter. They get rendered once when registered (with
empty manifest.dump = {}), but never re-rendered after
processCollectionItems populates manifest.dump.
Evidence during build:
File: .data/content/contents.sqlite
Content: NEW ✅
────────────────────────────────────────
File: dist/dump.{collection}.sql (from fullDatabaseRawDumpTemplate)
Content: NEW ✅
────────────────────────────────────────
File: .nuxt/content/raw/dump.{collection}.sql (per-collection template)
Content: OLD ❌
────────────────────────────────────────
File: dist/__nuxt_content/{collection}/sql_dump.txt (prerendered)
Content: OLD ❌
Suggested fix:
Add per-collection dump templates to the updateTemplates filter:
const perCollectionDumps = manifest.collections
.filter((c) => !c.private)
.map((c) => `content/raw/dump.${c.name}.sql`);
await updateTemplates({
filter: (template) => [
moduleTemplates.fullRawDump,
moduleTemplates.fullCompressedDump,
moduleTemplates.manifest,
moduleTemplates.components,
...perCollectionDumps
].includes(template.filename)
});
Workaround:
nuxt build
cp dist/dump.docs.sql dist/__nuxt_content/docs/sql_dump.txt
cp dist/dump.blog.sql dist/__nuxt_content/blog/sql_dump.txt
wrangler --cwd dist pages deploy
Additional context
No response