docs: add server components guide and mostly-static site recipe - #35778
Conversation
@nuxt/kit
@nuxt/nitro-server
nuxt
@nuxt/rspack-builder
@nuxt/schema
@nuxt/vite-builder
@nuxt/webpack-builder
commit: |
This comment has been minimized.
This comment has been minimized.
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 `@docs/3.guide/6.going-further/1.features.md`:
- Around line 44-50: Clarify the introductory description of noScripts to state
that it disables Nuxt-generated scripts and JavaScript resource hints, rather
than all JavaScript. Keep the documented option values and behavior unchanged,
including user-authored and third-party script elements.
🪄 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: 62c27346-6ff7-4fec-89ff-396562472bf2
📒 Files selected for processing (8)
docs/2.directory-structure/1.app/1.components.mddocs/3.guide/1.concepts/1.rendering.mddocs/3.guide/1.concepts/6.server-components.mddocs/3.guide/2.best-practices/performance.mddocs/3.guide/5.recipes/5.mostly-static-sites.mddocs/3.guide/6.going-further/1.experimental-features.mddocs/3.guide/6.going-further/1.features.mddocs/4.api/1.components/8.nuxt-island.md
9ad5b4d to
6c5459d
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
docs/3.guide/6.going-further/1.features.md (1)
44-44: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winScope noScripts claims to Nuxt-generated JavaScript.
noScriptsdisables Nuxt scripts and JavaScript resource hints; it does not establish that arbitrary scripts are removed. (nuxt.com)
docs/3.guide/6.going-further/1.features.md#L44-L44: replace “pure HTML and CSS” with scoped wording.docs/3.guide/5.recipes/5.mostly-static-sites.md#L28-L28: qualify “effectively zero JavaScript cost”.docs/3.guide/5.recipes/5.mostly-static-sites.md#L99-L101: clarify that the routes ship without Nuxt-generated JavaScript, not necessarily all scripts.🤖 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 `@docs/3.guide/6.going-further/1.features.md` at line 44, Scope the documentation claims about noScripts to Nuxt-generated JavaScript: in docs/3.guide/6.going-further/1.features.md:44, replace “pure HTML and CSS” with wording that excludes Nuxt scripts and JavaScript resource hints; in docs/3.guide/5.recipes/5.mostly-static-sites.md:28, qualify “effectively zero JavaScript cost”; and in docs/3.guide/5.recipes/5.mostly-static-sites.md:99-101, clarify that routes omit Nuxt-generated JavaScript without claiming all scripts are removed.Source: MCP tools
🤖 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 `@docs/3.guide/5.recipes/5.mostly-static-sites.md`:
- Line 81: Update the hydrate-never explanation in the documentation to state
that the component never hydrates unless a prop change triggers hydration,
removing the claim that its JavaScript is never executed while preserving the
surrounding server-rendering context.
---
Duplicate comments:
In `@docs/3.guide/6.going-further/1.features.md`:
- Line 44: Scope the documentation claims about noScripts to Nuxt-generated
JavaScript: in docs/3.guide/6.going-further/1.features.md:44, replace “pure HTML
and CSS” with wording that excludes Nuxt scripts and JavaScript resource hints;
in docs/3.guide/5.recipes/5.mostly-static-sites.md:28, qualify “effectively zero
JavaScript cost”; and in docs/3.guide/5.recipes/5.mostly-static-sites.md:99-101,
clarify that routes omit Nuxt-generated JavaScript without claiming all scripts
are removed.
🪄 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 Plus
Run ID: dea8c9ef-32a2-420c-b04c-e51827c73816
📒 Files selected for processing (8)
docs/2.directory-structure/1.app/1.components.mddocs/3.guide/1.concepts/1.rendering.mddocs/3.guide/1.concepts/6.server-components.mddocs/3.guide/2.best-practices/performance.mddocs/3.guide/5.recipes/5.mostly-static-sites.mddocs/3.guide/6.going-further/1.experimental-features.mddocs/3.guide/6.going-further/1.features.mddocs/4.api/1.components/8.nuxt-island.md
🚧 Files skipped from review as they are similar to previous changes (1)
- docs/3.guide/1.concepts/1.rendering.md
| </template> | ||
| ``` | ||
|
|
||
| `hydrate-never` is particularly useful on content sites: the component's HTML is server-rendered, but it is never hydrated, so its JavaScript is never executed (though prop changes will still trigger hydration). |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🌐 Web query:
Nuxt 4 hydrate-never prop changes trigger hydration documentation
💡 Result:
In Nuxt 4, it is explicitly documented that any prop change to a component using a lazy hydration strategy—including the hydrate-never strategy—will trigger immediate hydration [1][2][3]. This behavior is an expected characteristic of how Vue handles async components: when an update to the component's props occurs, Vue skips the lazy hydration strategy and proceeds to hydrate the component immediately [2][4]. Because of this, developers are advised to avoid using hydrate-never on components that require interactivity or expect reactive prop updates [1][3]. For context, this was previously documented in a way that sometimes caused confusion, but official documentation has been updated to clarify that this trigger is expected behavior [2]. If you need a component to truly never hydrate, it is recommended to use a server-only component instead of relying solely on the hydrate-never prop [5].
Citations:
- 1: https://dev.nuxt.com/docs/4.x/guide/directory-structure/app/components
- 2: perf(nuxt): remove watcher from
hydrate-whenlazy hydration strategy #33199 - 3: https://nuxt.com/docs/4.x/directory-structure/app/components
- 4: Console warning for
hydrate-whenstrategy #33193 - 5: feat(nuxt): delayed/lazy hydration support #26468
🌐 Web query:
Nuxt 4 hydrate-never JS never execute prop changes trigger hydration
💡 Result:
In Nuxt 4, the hydrate-never strategy is intended to prevent a component from undergoing Vue's hydration process, keeping it static [1][2][3]. However, a critical behavior of Vue's lazy hydration mechanism is that any change to the props of a lazily hydrated component will cause Vue to skip the intended lazy strategy and trigger hydration immediately [1][4][5]. This behavior applies to all lazy hydration strategies, including hydrate-never [4][5]. If a component configured with hydrate-never receives a prop change, it will effectively be hydrated by Vue, despite the directive [1][4]. This is considered expected behavior within Vue's core hydration logic [4][5]. Key points regarding this behavior: - Scope: This impacts all components using Nuxt's built-in lazy hydration strategies [4][5]. - Expected Behavior: Because this is a core Vue behavior regarding async component updates, it is not considered a bug, but rather an inherent limitation of applying lazy hydration strategies to components that receive dynamic props [6][4]. - Implementation Note: If you require a component to remain truly static and never hydrate regardless of prop changes, using Nuxt's Server Components (often referred to as Islands) is the recommended alternative, as they are architecturally isolated from the client-side hydration process [5].
Citations:
- 1: https://dev.nuxt.com/docs/4.x/guide/directory-structure/app/components
- 2: https://nuxt.com/docs/4.x/api/utils/define-lazy-hydration-component
- 3: feat(nuxt): support lazy hydration macros #31192
- 4: perf(nuxt): remove watcher from
hydrate-whenlazy hydration strategy #33199 - 5: https://nuxt.com/docs/4.x/directory-structure/app/components
- 6: Console warning for
hydrate-whenstrategy #33193
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="docs/3.guide/5.recipes/5.mostly-static-sites.md"
if [ -f "$file" ]; then
echo "== file exists =="
wc -l "$file"
echo "== target excerpt =="
sed -n '70,90p' "$file" | nl -ba -v70
else
echo "missing $file"
echo "matching files:"
fd -i 'mostly-static-sites.md' .
fiRepository: nuxt/nuxt
Length of output: 278
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="docs/3.guide/5.recipes/5.mostly-static-sites.md"
echo "== target excerpt =="
sed -n '70,90p' "$file"Repository: nuxt/nuxt
Length of output: 912
Correct the hydrate-never explanation.
A prop change can trigger hydration, so the component’s JavaScript is not guaranteed to stay unexecuted. Say it “never hydrates unless a prop change triggers hydration” instead of “its JavaScript is never executed”.
🤖 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 `@docs/3.guide/5.recipes/5.mostly-static-sites.md` at line 81, Update the
hydrate-never explanation in the documentation to state that the component never
hydrates unless a prop change triggers hydration, removing the claim that its
JavaScript is never executed while preserving the surrounding server-rendering
context.
Source: MCP tools
🔗 Linked issue
📚 Description
this adds a separate server components guide (mostly pulled out of the
/directory-structure/app/componentspage and a 'Mostly Static Sites' recipe to help people optimise static pages with prerendering, lazy hydration, etc.