feat(nuxt): forward destination preload hints on link prefetch#35144
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
✅ Files skipped from review due to trivial changes (1)
WalkthroughThis pull request implements the experimental prefetchPreloadTags feature: adds schema/config and generated export, records user-defined preload/modulepreload link tags during SSR into ssrContext.payload.prefetchLinks, updates payload splitting and renderer to preserve or strip that field appropriately, injects downgraded rel="prefetch" links on client prefetch with lifecycle cleanup, and includes tests, fixtures and documentation. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/schema/src/types/schema.ts`:
- Around line 1520-1528: Update the documentation for the prefetchPreloadTags
option to mention that both rel="preload" and rel="modulepreload" link hints are
forwarded (and downgraded to rel="prefetch"), not just preload; reference the
implementation by noting FORWARDED_RELS includes 'preload' and 'modulepreload'
(see the constant in prefetch-preload-tags.server.ts) and adjust the description
text in the prefetchPreloadTags JSDoc accordingly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 5b67d1f5-b2d4-457d-97bc-dab1e06b0bd0
⛔ Files ignored due to path filters (2)
packages/nuxt/package.jsonis excluded by!**/package.jsonpnpm-lock.yamlis excluded by!**/pnpm-lock.yaml,!pnpm-lock.yaml
📒 Files selected for processing (14)
docs/3.guide/6.going-further/1.experimental-features.mdpackages/nitro-server/src/runtime/handlers/renderer.tspackages/nitro-server/src/runtime/utils/renderer/payload.tspackages/nuxt/meta.jspackages/nuxt/src/app/nuxt.tspackages/nuxt/src/app/plugins/payload.client.tspackages/nuxt/src/app/plugins/prefetch-preload-tags.server.tspackages/nuxt/src/core/nuxt.tspackages/nuxt/src/core/templates.tspackages/schema/src/config/experimental.tspackages/schema/src/types/schema.tstest/basic.test.tstest/fixtures/basic/app/pages/prefetch/server-components.vuetest/fixtures/basic/nuxt.config.ts
| /** | ||
| * When a `<NuxtLink>` is prefetched and the destination route has a `_payload.json`, forward any `<link rel="preload">` hints that the destination set via `useHead` (or via modules like `@nuxt/image`'s `<NuxtImg preload>`) into the current document. | ||
| * | ||
| * The forwarded links are downgraded from `rel="preload"` to `rel="prefetch"` so they don't compete with the current page's critical resources. Only user-defined head tags are forwarded; build-time JS/CSS chunk preloads are not. | ||
| * | ||
| * @default false | ||
| * @see [Issue #34953](https://github.com/nuxt/nuxt/issues/34953) | ||
| */ | ||
| prefetchPreloadTags: boolean |
There was a problem hiding this comment.
Documentation should mention modulepreload in addition to preload.
The documentation currently states "forward any <link rel="preload"> hints" and mentions downgrading from rel="preload", but the implementation (in prefetch-preload-tags.server.ts line 11) forwards both preload and modulepreload via FORWARDED_RELS = new Set(['preload', 'modulepreload']).
📝 Suggested documentation clarification
/**
- * When a `<NuxtLink>` is prefetched and the destination route has a `_payload.json`, forward any `<link rel="preload">` hints that the destination set via `useHead` (or via modules like `@nuxt/image`'s `<NuxtImg preload>`) into the current document.
+ * When a `<NuxtLink>` is prefetched and the destination route has a `_payload.json`, forward any `<link rel="preload">` or `<link rel="modulepreload">` hints that the destination set via `useHead` (or via modules like `@nuxt/image`'s `<NuxtImg preload>`) into the current document.
*
- * The forwarded links are downgraded from `rel="preload"` to `rel="prefetch"` so they don't compete with the current page's critical resources. Only user-defined head tags are forwarded; build-time JS/CSS chunk preloads are not.
+ * The forwarded links are downgraded from `rel="preload"` or `rel="modulepreload"` to `rel="prefetch"` so they don't compete with the current page's critical resources. Only user-defined head tags are forwarded; build-time JS/CSS chunk preloads are not.
*
* `@default` false
* `@see` [Issue `#34953`](https://github.com/nuxt/nuxt/issues/34953)
*/📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /** | |
| * When a `<NuxtLink>` is prefetched and the destination route has a `_payload.json`, forward any `<link rel="preload">` hints that the destination set via `useHead` (or via modules like `@nuxt/image`'s `<NuxtImg preload>`) into the current document. | |
| * | |
| * The forwarded links are downgraded from `rel="preload"` to `rel="prefetch"` so they don't compete with the current page's critical resources. Only user-defined head tags are forwarded; build-time JS/CSS chunk preloads are not. | |
| * | |
| * @default false | |
| * @see [Issue #34953](https://github.com/nuxt/nuxt/issues/34953) | |
| */ | |
| prefetchPreloadTags: boolean | |
| /** | |
| * When a `<NuxtLink>` is prefetched and the destination route has a `_payload.json`, forward any `<link rel="preload">` or `<link rel="modulepreload">` hints that the destination set via `useHead` (or via modules like `@nuxt/image`'s `<NuxtImg preload>`) into the current document. | |
| * | |
| * The forwarded links are downgraded from `rel="preload"` or `rel="modulepreload"` to `rel="prefetch"` so they don't compete with the current page's critical resources. Only user-defined head tags are forwarded; build-time JS/CSS chunk preloads are not. | |
| * | |
| * `@default` false | |
| * `@see` [Issue `#34953`](https://github.com/nuxt/nuxt/issues/34953) | |
| */ | |
| prefetchPreloadTags: boolean |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/schema/src/types/schema.ts` around lines 1520 - 1528, Update the
documentation for the prefetchPreloadTags option to mention that both
rel="preload" and rel="modulepreload" link hints are forwarded (and downgraded
to rel="prefetch"), not just preload; reference the implementation by noting
FORWARDED_RELS includes 'preload' and 'modulepreload' (see the constant in
prefetch-preload-tags.server.ts) and adjust the description text in the
prefetchPreloadTags JSDoc accordingly.
@nuxt/kit
@nuxt/nitro-server
nuxt
@nuxt/rspack-builder
@nuxt/schema
@nuxt/vite-builder
@nuxt/webpack-builder
commit: |
Merging this PR will not alter performance
Comparing Footnotes
|
(cherry picked from commit dd22da8)
(cherry picked from commit dd22da8)
(cherry picked from commit dd22da8)
🔗 Linked issue
resolves #34953
inspired by https://github.com/dan-hale/NuxtFaster/blob/master/plugins/preload.ts (cc: @dan-hale)
📚 Description
When
<NuxtLink prefetch>(or the default visibility-based prefetch) fires for a route that has payload extraction, we already fetch the destination's_payload.jsonand prime its data + chunks. This PR additionally forwards any<link rel="preload">/<link rel="modulepreload">hints the destination has set viauseHead(or via modules like@nuxt/image's<NuxtImg preload>) into the current document, downgraded torel="prefetch"so they don't compete with the current page's critical resources.To benefit, you need to opt-in:
Once enabled, a page like this:
will have its hero image fetched in the background as soon as a
<NuxtLink to="/product/123">to it becomes visible (or is hovered, depending onprefetchOn), instead of waiting until the user clicks through.