refactor(nuxt): move island renderer into its own event handler#31386
refactor(nuxt): move island renderer into its own event handler#31386
Conversation
|
|
@nuxt/kit
nuxt
@nuxt/rspack-builder
@nuxt/schema
@nuxt/vite-builder
@nuxt/webpack-builder
commit: |
CodSpeed Performance ReportMerging #31386 will not alter performanceComparing Summary
|
ea566a0 to
29ed300
Compare
6e56299 to
8250de0
Compare
WalkthroughThis pull request restructures various aspects of the Nuxt codebase. Type exports have been reorganised by moving the island-related types to a new module and adjusting the export statements accordingly. The server initialisation process now includes an additional condition to add a new server handler for handling requests aimed at island components. Several functions and interfaces handling island rendering have been removed from the primary renderer, while new functions to create and manage the SSR context, alongside error handling, have been introduced. Furthermore, a new utility for inlining styles and a dedicated module for processing island responses and HTML manipulations have been added. Minor adjustments have been made to the build files and tests to reflect these changes. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
⏰ Context from checks skipped due to timeout of 90000ms (3)
🔇 Additional comments (3)
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (10)
packages/nuxt/src/core/runtime/nitro/utils/renderer/inline-styles.ts (1)
4-14: Consider adding error handling for style retrieval.Everything appears correct, but you might want to handle potential load failures in
styleMap[mod]()with a try/catch or fallback for safer runtime behaviour.packages/nuxt/src/core/runtime/nitro/utils/renderer/app.ts (1)
12-36: Consider unifying noSSR logic
ThecreateSSRContextfunction neatly sets up the SSR context, including environment checks and prerender logic. As a small improvement, you might consider extracting the repeating noSSR condition checks into a separate helper to maintain clarity.packages/nuxt/src/core/runtime/nitro/handlers/__nuxt_island.ts (3)
30-42: SSR context creation & island context
You correctly initialise both SSR and island contexts here. A minor recommendation might be to verify thatislandContext.urlis safe or expected if altered. Overall, this is a solid approach.
71-85: Constructing the island head
Collecting all head entries intoislandHeadensures consolidated control over metadata. Consider deduplicating entries if multiple identical tags appear.
103-128: Island context retrieval and TODO
getIslandContextgracefully combines URL parsing with property extraction. TheTODO: Strict validation for urlindicates a known gap. If you need assistance implementing robust validation, feel free to request.packages/nuxt/src/core/runtime/nitro/utils/renderer/build-files.ts (2)
21-21: Dynamic server entry import
This approach provides flexibility, though be mindful of error handling if the file fails to load.
24-26: Client manifest import
Similarly, ensure proper fallback if the manifest is missing or invalid. Otherwise, this dynamic import pattern is consistent.packages/nuxt/src/core/runtime/nitro/handlers/renderer.ts (1)
87-87: Consider using optional chaining in the condition.
You can simplify this condition by usingif (ssrError?.statusCode) { ... }. This helps reduce nesting and aligns with the static analysis hint.-if (ssrError && ssrError.statusCode) { +if (ssrError?.statusCode) {🧰 Tools
🪛 Biome (1.9.4)
[error] 87-87: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
packages/nuxt/src/core/runtime/nitro/utils/renderer/islands.ts (2)
6-14: Graceful HTML extraction ingetServerComponentHTML.
Returning the entire body if the root node is not matched ensures a safe fallback. If you want to debug or warn on unexpected content, consider adding logging for mismatch scenarios.
63-87: Island teleports replacement is robust.
This approach systematically patches the original HTML with teleport content based on SSR markers. Keep in mind any potential performance impact for very large HTML, though this is typically acceptable.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
packages/nuxt/src/app/types.ts(1 hunks)packages/nuxt/src/core/nuxt.ts(2 hunks)packages/nuxt/src/core/runtime/nitro/handlers/__nuxt_island.ts(1 hunks)packages/nuxt/src/core/runtime/nitro/handlers/renderer.ts(9 hunks)packages/nuxt/src/core/runtime/nitro/utils/renderer/app.ts(1 hunks)packages/nuxt/src/core/runtime/nitro/utils/renderer/build-files.ts(3 hunks)packages/nuxt/src/core/runtime/nitro/utils/renderer/inline-styles.ts(1 hunks)packages/nuxt/src/core/runtime/nitro/utils/renderer/islands.ts(1 hunks)test/bundle.test.ts(3 hunks)
🧰 Additional context used
🧬 Code Definitions (4)
packages/nuxt/src/core/runtime/nitro/utils/renderer/inline-styles.ts (1)
packages/nuxt/src/core/runtime/nitro/utils/renderer/build-files.ts (1)
getSSRStyles(118-118)
packages/nuxt/src/core/runtime/nitro/handlers/renderer.ts (5)
packages/nuxt/src/app/nuxt.ts (1)
NuxtSSRContext(60-85)packages/nuxt/src/core/runtime/nitro/utils/renderer/app.ts (2)
createSSRContext(12-36)setSSRError(38-42)packages/nuxt/src/core/runtime/nitro/utils/renderer/build-files.ts (1)
getRenderer(113-115)packages/nuxt/src/core/runtime/nitro/utils/cache.ts (1)
payloadCache(3-3)packages/nuxt/src/core/runtime/nitro/utils/renderer/payload.ts (1)
renderPayloadResponse(12-24)
packages/nuxt/src/core/runtime/nitro/handlers/__nuxt_island.ts (5)
packages/nuxt/src/core/runtime/nitro/utils/renderer/app.ts (1)
createSSRContext(12-36)packages/nuxt/src/core/runtime/nitro/utils/renderer/build-files.ts (1)
getRenderer(113-115)packages/nuxt/src/core/runtime/nitro/utils/renderer/inline-styles.ts (1)
renderInlineStyles(4-15)packages/nuxt/src/app/types.ts (2)
NuxtIslandResponse(8-8)NuxtIslandContext(8-8)packages/nuxt/src/core/runtime/nitro/utils/renderer/islands.ts (5)
NuxtIslandResponse(103-110)getServerComponentHTML(11-14)getClientIslandResponse(32-46)getSlotIslandResponse(20-30)NuxtIslandContext(94-101)
packages/nuxt/src/core/runtime/nitro/utils/renderer/islands.ts (1)
packages/nuxt/src/app/types.ts (2)
NuxtIslandResponse(8-8)NuxtIslandContext(8-8)
🪛 Biome (1.9.4)
packages/nuxt/src/core/runtime/nitro/handlers/renderer.ts
[error] 87-87: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
🔇 Additional comments (25)
packages/nuxt/src/app/types.ts (1)
7-8: Re-export changes look valid.These updated re-exports for island-related types appear consistent and tidy. No concerns.
packages/nuxt/src/core/nuxt.ts (2)
9-9: New import is appropriate.Adding
addServerHandleris needed for registering the new route. Approved.
628-631: Island route registration is correct.This handler logic is clear. Consider verifying it does not conflict with existing routes, but otherwise it looks fine.
test/bundle.test.ts (1)
61-61: Updated snapshot values are acceptable.These new inline snapshot values are consistent with the larger server bundles introduced by the new island rendering logic.
Also applies to: 64-64, 98-98, 101-101, 120-120
packages/nuxt/src/core/runtime/nitro/utils/renderer/app.ts (3)
1-9: Imports appear well-structured
These imports and type references look consistent, and the@ts-expect-errordirective is clearly explained. No issues found.
10-11: Constant definition
DefiningPRERENDER_NO_SSR_ROUTEShere is straightforward and keeps the prerender routes clearly visible in the code.
38-42: Error handling
ThesetSSRErrorfunction succinctly marks the context as erroneous and injects details into the payload. This helps keep error states consolidated.packages/nuxt/src/core/runtime/nitro/handlers/__nuxt_island.ts (6)
1-14: Import organisation
These imports are well-organised, providing clear entry points for rendering, caching, and event utilities. No issues identified.
16-28: Handler initialisation
DefiningISLAND_SUFFIX_REand setting JSON response headers indefineEventHandleris straightforward and intuitive.
43-46: Post-render hook
Callingapp:renderedallows for flexible post-render operations. This helps maintain separation of concerns and is a good practice.
47-69: Inline styles & development styling
Rendering inline styles and conditionally adding CSS links in dev mode is well handled. Ensuring no duplication of links in production is a nice efficiency measure.
86-93: Island response assembly
Building theNuxtIslandResponseobject here is clear and expressive. The integration with server and client components is structured well.
94-101: Prerender caching
Storing the island output in caches facilitates subsequent quick lookups. The approach is robust for prerendered deployments.packages/nuxt/src/core/runtime/nitro/utils/renderer/build-files.ts (4)
29-29: Lazy-cached SSR renderer
WrappinggetSSRRendererwithlazyCachedFunctionmakes sense for performance. No concerns here.
60-60: Lazy-cached SPA renderer
Applying the same pattern for the SPA renderer is consistent and ensures one-time setup. Looks good.
114-115:getRendererunifies SSR & SPA
ExportinggetRendererto route logic through SSR or SPA rendering is cohesive. This centralises decision-making effectively.
117-124: Style retrieval
getSSRStylesandgetEntryIdsguarantee the retrieval of styles for inline injection. This is a straightforward, well-structured solution.packages/nuxt/src/core/runtime/nitro/handlers/renderer.ts (4)
9-23: All newly introduced imports are appropriately used.
These imports accurately reflect their usage across the file, such as payload caching, SSR context creation, and inline style rendering.
95-98: Validate edge cases for URL rewriting.
When extracting the preceding segment of the URL, ensure that unusual scenarios (e.g. no slashes in the path) are handled gracefully. The fallback to'/'is correct, but keep an eye on potential usage conflicts when modifyingevent.node.req.url.Do you want to confirm or test how the system behaves with paths that lack slashes?
107-108: Neat approach for handling disabling SSR routes.
SettingssrContext.noSSRto respectrouteOptions.ssr === falseis a clear and logical pattern.
273-281: Final response construction looks good.
The HTML is rendered with proper headers, status, and content type. No issues spotted here.packages/nuxt/src/core/runtime/nitro/utils/renderer/islands.ts (4)
20-30: Slot island response logic is concise.
Retrieving slots fromssrContext.islandContext.slotsand merging with fallback content is well-structured. The code clearly handles absent slots by returningundefined.
32-46: Client island response generation is clear.
Removing the teleport anchors viareplaceAllis a practical approach to avoid hydration issues. The function appropriately organises slots in the returned object.
48-61: Clean slot teleport processing.
Using a straightforward loop and regex matching to locate teleports is a good pattern. No further issues found.
89-117: Interfaces for islands improve clarity and maintainability.
The definition ofNuxtIslandSlotResponse,NuxtIslandContext,NuxtIslandResponse, andNuxtIslandClientResponseis precise and evidently suited to the use cases in the new SSR flow.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (4)
packages/nuxt/src/core/nuxt.ts (1)
628-635: Conditionally adding the__nuxt_islandhandler.Registering the island handler (
addServerHandler) under'/__nuxt_island/**'is a good solution for supporting the island functionality based on the current environment,componentIslandsconfiguration, and server/client mode checks.Consider verifying that no conflicts exist with other server routes and that any requests for this route inherently require the intended permissions/headers. Otherwise, this change looks solid.
packages/nuxt/src/core/runtime/nitro/handlers/island.ts (3)
43-69: Inline styles and development mode stylesheet injection.Expanding the head with inlined styles and conditionally adding stylesheets in dev mode addresses CSS injection for scoped resources. Be mindful of potential performance implications if too many styles are inlined, especially in larger projects. Otherwise, this logic is a solid approach for local development.
71-101: Constructing the island response and caching.Populating the
islandHead, assembling the server-rendered HTML, and caching the final island response are essential to the island concept. The response structure is coherent. For future enhancements, consider fallback or retry logic when fetching from or setting to the cache, especially in distributed hosting scenarios.
103-128: Island context extraction and validation.Retrieving the island context from the request is straightforward, but the TODO comments indicate areas for stricter URL and props validation. This is essential to secure the application against malformed requests. Consider adding robust validation or sanitisation steps for production reliability.
Do you want help generating a snippet with stricter property checks (e.g. using runtime validators) for the
urlandpropsfields?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
packages/nuxt/src/core/nuxt.ts(2 hunks)packages/nuxt/src/core/runtime/nitro/handlers/island.ts(1 hunks)test/bundle.test.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- test/bundle.test.ts
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: code
- GitHub Check: build
🔇 Additional comments (3)
packages/nuxt/src/core/nuxt.ts (1)
9-9: Successfully importedaddServerHandler.The newly added import of
addServerHandlerfrom@nuxt/kitis correct and aligns with the usage in subsequent lines. No concerns regarding this addition.packages/nuxt/src/core/runtime/nitro/handlers/island.ts (2)
1-17: Imports and constant definition.All required imports are neatly organised, covering SSR context creation, caching, and relevant modules for island handling. The
ISLAND_SUFFIX_REconstant clearly separates JSON suffix handling logic. This section appears well-structured.
18-41: Core event handler setup and error handling.Defining a dedicated event handler for rendering islands sets a clear entry point. Error handling with
app:errorensures that any rendering failures are captured by Nuxt error hooks. This approach looks correct and maintainable.
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (12)
packages/nuxt/src/core/runtime/nitro/handlers/island.ts (5)
16-16: Track pending TODO items.
// TODO: remove for v4implies an upcoming removal. Make sure to create or link to an issue to track this removal so it won't be overlooked.Do you need assistance opening a ticket to ensure this is addressed before v4?
18-28: Consider validating JSON content header.
You are setting the response content type to JSON. If the request might return an error message or HTML snippet under some conditions, ensure that the code consistently returns valid JSON.
42-45: Surface more descriptive error messages.
Within thecatchblock, consider enhancing error logs to include context about the failed island rendering. This will aid debugging.
49-53: Watch out for potential memory bloat with inlined styles.
Inlined styles can quickly grow and inflate payload size. Consider implementing cache or usage checks for large modules to maintain performance.
86-86: Confirm the rationale for legacy support.
The TODO at this line suggests temporary support that might be removed later. Ensure you clearly communicate to maintainers or downstream consumers about the upcoming deprecation.packages/nuxt/src/core/runtime/nitro/handlers/renderer.ts (5)
11-11: Watch for performance overhead inrenderSSRHead.
SincerenderSSRHeadcan become expensive on large projects, ensure it’s not invoked unnecessarily.
92-99: Ensure accurate route rewriting for payload extraction.
Modifyingevent._pathat line 98 can lead to confusion if other parts of the system rely onevent.path. Document or double-check these references.
112-114: Clarify logic behind_PAYLOAD_EXTRACTION.
Combiningimport.meta.prerenderchecks withprocess.env.NUXT_PAYLOAD_EXTRACTIONcan become convoluted. Consider extracting into a helper function to keep this snippet simpler.
198-213: Optimise CSS loading in production.
Currently, all CSS resources are pushed into<head>. If the project grows, explore lazy-loading or chunk-based strategies to keep overhead minimal.
243-254: Account for script type in older browsers.
Some older browsers might fail to parse modules withtype='module'. If supporting legacy browsers, consider a fallback or transpile approach.packages/nuxt/src/core/runtime/nitro/utils/renderer/islands.ts (2)
11-14: Handle missing root node gracefully.
If regex fails to match the root node, you return the entirebody. Consider logging a debug message or warning when fallback logic is triggered to aid debugging.
32-46: Consider deduplicating repeated code across component & slot responses.
getClientIslandResponseparallels the slot approach. Factor out shared logic to keep maintainability high and reduce potential bugs.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
packages/nuxt/src/core/runtime/nitro/handlers/island.ts(1 hunks)packages/nuxt/src/core/runtime/nitro/handlers/renderer.ts(9 hunks)packages/nuxt/src/core/runtime/nitro/utils/renderer/app.ts(1 hunks)packages/nuxt/src/core/runtime/nitro/utils/renderer/build-files.ts(3 hunks)packages/nuxt/src/core/runtime/nitro/utils/renderer/islands.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/nuxt/src/core/runtime/nitro/utils/renderer/app.ts
- packages/nuxt/src/core/runtime/nitro/utils/renderer/build-files.ts
🧰 Additional context used
🧬 Code Definitions (3)
packages/nuxt/src/core/runtime/nitro/handlers/island.ts (3)
packages/nuxt/src/core/runtime/nitro/utils/renderer/app.ts (1)
createSSRContext(12-34)packages/nuxt/src/core/runtime/nitro/utils/renderer/build-files.ts (1)
getSSRRenderer(29-57)packages/nuxt/src/core/runtime/nitro/utils/renderer/islands.ts (5)
NuxtIslandResponse(103-110)getServerComponentHTML(11-14)getClientIslandResponse(32-46)getSlotIslandResponse(20-30)NuxtIslandContext(94-101)
packages/nuxt/src/core/runtime/nitro/handlers/renderer.ts (5)
packages/nuxt/src/app/nuxt.ts (1)
NuxtSSRContext(60-85)packages/nuxt/src/core/runtime/nitro/utils/renderer/app.ts (2)
createSSRContext(12-34)setSSRError(36-40)packages/nuxt/src/core/runtime/nitro/utils/renderer/build-files.ts (1)
getRenderer(113-115)packages/nuxt/src/core/runtime/nitro/utils/cache.ts (1)
payloadCache(3-3)packages/nuxt/src/core/runtime/nitro/utils/renderer/payload.ts (1)
renderPayloadResponse(12-24)
packages/nuxt/src/core/runtime/nitro/utils/renderer/islands.ts (1)
packages/nuxt/src/app/types.ts (2)
NuxtIslandResponse(8-8)NuxtIslandContext(8-8)
🪛 Biome (1.9.4)
packages/nuxt/src/core/runtime/nitro/handlers/renderer.ts
[error] 87-87: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
⏰ Context from checks skipped due to timeout of 90000ms (3)
- GitHub Check: build
- GitHub Check: codeql (javascript-typescript)
- GitHub Check: code
🔇 Additional comments (10)
packages/nuxt/src/core/runtime/nitro/handlers/island.ts (1)
30-37: Short-circuit the rendering flow if island context is invalid.
After extractingislandContext, consider validating required properties (likename) before proceeding to render. It prevents unexpected behaviour if the context is incomplete or corrupted.packages/nuxt/src/core/runtime/nitro/handlers/renderer.ts (7)
9-9: Ensure graceful fallback for unknown queries.
When importinggetQueryfromh3, confirm that it won't cause unexpected behaviour if the query is large, missing, or malformed.
17-18: Verify presence of caching strategy.
You now use apayloadCachebut ensure that the entire route rendering is consistent with the intended caching model, especially under high concurrency.
81-84: Avoid potential duplication in SSR context creation.
You create the SSR context at line 81. Confirm that it’s only done once per request and that previous partial contexts are not reused.
87-90: Optional chaining trigger from static analysis.
Static analysis suggests changing thessrError && ssrError.statusCodecheck to optional chaining. While not strictly necessary, it may simplify your condition:-if (ssrError && ssrError.statusCode) { +if (ssrError?.statusCode) {🧰 Tools
🪛 Biome (1.9.4)
[error] 87-87: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
107-108: Re-check SSR toggling logic.
SettingssrContext.noSSRtotrueifrouteOptions.ssr === falsemight ignore other conditions that disable SSR. Confirm no collisions occur with environment variables or runtime config.
116-116: Check rendering fallback for no renderer found.
getRenderer(ssrContext)can theoretically return undefined if something misfires. Consider handling that gracefully to avoid runtime exceptions.
225-239: Confirm script insertion order.
Payload scripts are appended withtagPosition: 'bodyClose'at line 236. Confirm that any dependencies they rely on are loaded beforehand.packages/nuxt/src/core/runtime/nitro/utils/renderer/islands.ts (2)
1-5: EnsureappRootTagis guaranteed to exist.
If#internal/nuxt.config.mjsdoesn't provide a validappRootTag,ROOT_NODE_REGEXmight fail or produce misleading matches.
20-30: Guard against empty slot data.
IfssrContext.islandContext.slotsis empty or invalid, ensure the fallback logic doesn’t degrade performance or produce an unhandled error.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/nuxt/src/core/nuxt.ts(2 hunks)test/bundle.test.ts(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- test/bundle.test.ts
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: build
- GitHub Check: code
🔇 Additional comments (1)
packages/nuxt/src/core/nuxt.ts (1)
9-9: Import statement addition for server handlersThe updated import statement now includes
addServerHandlerandaddServerTemplate, which are required for the new island renderer functionality being implemented.
| // sync conditions with /packages/nuxt/src/core/templates.ts#L539 | ||
| addServerTemplate({ | ||
| filename: '#internal/nuxt/island-renderer.mjs', | ||
| getContents () { | ||
| if (nuxt.options.dev || nuxt.options.experimental.componentIslands !== 'auto' || nuxt.apps.default?.pages?.some(p => p.mode === 'server') || nuxt.apps.default?.components?.some(c => c.mode === 'server' && !nuxt.apps.default?.components.some(other => other.pascalName === c.pascalName && other.mode === 'client'))) { | ||
| return `export { default } from '${resolve(distDir, 'core/runtime/nitro/handlers/island')}'` | ||
| } | ||
| return `export default defineEventHandler(() => {})` | ||
| }, | ||
| }) | ||
| addServerHandler({ | ||
| route: '/__nuxt_island/**', | ||
| handler: '#internal/nuxt/island-renderer.mjs', | ||
| }) | ||
|
|
There was a problem hiding this comment.
💡 Verification agent
🧩 Analysis chain
Island renderer implementation looks good, but timing concern persists
The code effectively separates the island rendering logic into its own server endpoint, which aligns with the PR objective of enhancing readability by moving this functionality out of the main render handler.
However, there's still a potential issue with accessing nuxt.apps.default before it's fully initialized, as noted in a previous review. While the optional chaining (?.) prevents errors, it might result in incorrect behavior if evaluation happens too early.
Consider moving this server handler registration after a point where nuxt.apps.default is guaranteed to be initialized, perhaps after the initNitro call on line 759 or by using a hook to defer this registration.
🌐 Web query:
When is nuxt.apps.default initialized in the Nuxt lifecycle?
💡 Result:
In Nuxt 3, the nuxtApp instance (commonly referred to as the runtime context) is initialized during the app creation phase of the lifecycle. This occurs in two key phases:
Server-Side Initialization
- After Nitro server setup but before server middleware/plugins
ThenuxtAppis initialized during Step 3 (Initialize Nuxt and Execute Nuxt App Plugins) of the server lifecycle[8]. This happens after Nitro server initialization but before server middleware and plugin execution.
Client-Side Initialization
- Early in client hydration
On the client,nuxtAppis initialized during the hydration process before executing client plugins and middleware[8].
Key Lifecycle Hook
The app:created hook signals the availability of nuxtApp:
nuxtApp.hook('app:created', () => {
// nuxtApp is now accessible
})This hook executes:
- On the server: before server middleware and plugins[9]
- On the client: before client middleware and Vue component hydration[8]
Typical Access Points
nuxtApp becomes available in:
- Plugins via
defineNuxtPlugin[1][3] - Middleware through the runtime context
- Composables like
useNuxtApp()[4]
The initialization timing ensures nuxtApp exists before essential operations like store initialization (Pinia) and data fetching (useAsyncData/useFetch)[3][8].
Citations:
- 1: https://nuxt.com/docs/guide/going-further/hooks
- 2: https://vueschool.io/lessons/nuxt-lifecycle-hooks
- 3: https://krutiepatel.com/blog/nuxt-server-init-where-is-it-in-nuxt-3
- 4: https://blog.nuxtdojo.com/p/2-understanding-lifecycle-hooks-in
- 5: https://www.youtube.com/watch?v=A7A1N8FTxk4
- 6: https://app.studyraid.com/en/read/5826/127488/nuxt-lifecycle
- 7: https://v2.nuxt.com/docs/concepts/nuxt-lifecycle/
- 8: https://nuxt.com/docs/guide/concepts/nuxt-lifecycle
- 9: Running 'app:created' nuxt hook before middleware #27023
- 10: https://nuxt.com/docs/api/advanced/hooks
Potential Timing Issue with Island Renderer Registration
The separation of the island rendering logic into its own server endpoint is a clear improvement. However, there remains a timing concern regarding the access of nuxt.apps.default. Although the use of optional chaining prevents runtime errors, if this evaluation occurs before nuxt.apps.default is fully initialised (which, as per Nuxt’s lifecycle, happens during the app creation phase—typically in the app:created hook or after Nitro initialisation), it may lead to unintended behaviour.
- Actionable Recommendation:
Consider deferring the registration of the server handler until afternuxt.apps.defaultis guaranteed to be initialised. This could be achieved by moving the registration to a later point—such as after theinitNitrocall on line 759—or by using an appropriate lifecycle hook (e.g.app:created).

🔗 Linked issue
📚 Description
This PR moves nuxt island into its own endpoint for better readability of the render handler.
It also extract all shared logic within
utils/renderer.