mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-21 21:25:11 +00:00
fix(nuxt): render user-inserted links in island responses (#25219)
This commit is contained in:
parent
84eaf7ba2e
commit
20e88bb171
@ -229,9 +229,8 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
|
||||
}
|
||||
|
||||
// Check for island component rendering
|
||||
const islandContext = (process.env.NUXT_COMPONENT_ISLANDS && event.path.startsWith('/__nuxt_island'))
|
||||
? await getIslandContext(event)
|
||||
: undefined
|
||||
const isRenderingIsland = (process.env.NUXT_COMPONENT_ISLANDS as unknown as boolean && event.path.startsWith('/__nuxt_island'))
|
||||
const islandContext = isRenderingIsland ? await getIslandContext(event) : undefined
|
||||
|
||||
if (import.meta.prerender && islandContext && event.path && await islandCache!.hasItem(event.path)) {
|
||||
return islandCache!.getItem(event.path) as Promise<Partial<RenderResponse>>
|
||||
@ -241,7 +240,7 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
|
||||
let url = ssrError?.url as string || islandContext?.url || event.path
|
||||
|
||||
// Whether we are rendering payload route
|
||||
const isRenderingPayload = PAYLOAD_URL_RE.test(url) && !islandContext
|
||||
const isRenderingPayload = PAYLOAD_URL_RE.test(url) && !isRenderingIsland
|
||||
if (isRenderingPayload) {
|
||||
url = url.substring(0, url.lastIndexOf('/')) || '/'
|
||||
|
||||
@ -260,7 +259,9 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
|
||||
})
|
||||
// needed for hash hydration plugin to work
|
||||
const headEntryOptions: HeadEntryOptions = { mode: 'server' }
|
||||
head.push(appHead, headEntryOptions)
|
||||
if (!isRenderingIsland) {
|
||||
head.push(appHead, headEntryOptions)
|
||||
}
|
||||
|
||||
// Initialize ssr context
|
||||
const ssrContext: NuxtSSRContext = {
|
||||
@ -270,7 +271,7 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
|
||||
noSSR:
|
||||
!!(process.env.NUXT_NO_SSR) ||
|
||||
event.context.nuxt?.noSSR ||
|
||||
(routeOptions.ssr === false && !islandContext) ||
|
||||
(routeOptions.ssr === false && !isRenderingIsland) ||
|
||||
(import.meta.prerender ? PRERENDER_NO_SSR_ROUTES.has(url) : false),
|
||||
head,
|
||||
error: !!ssrError,
|
||||
@ -281,7 +282,7 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
|
||||
}
|
||||
|
||||
// Whether we are prerendering route
|
||||
const _PAYLOAD_EXTRACTION = import.meta.prerender && process.env.NUXT_PAYLOAD_EXTRACTION && !ssrContext.noSSR && !islandContext
|
||||
const _PAYLOAD_EXTRACTION = import.meta.prerender && process.env.NUXT_PAYLOAD_EXTRACTION && !ssrContext.noSSR && !isRenderingIsland
|
||||
const payloadURL = _PAYLOAD_EXTRACTION ? joinURL(useRuntimeConfig().app.baseURL, url, process.env.NUXT_JSON_PAYLOADS ? '_payload.json' : '_payload.js') : undefined
|
||||
if (import.meta.prerender) {
|
||||
ssrContext.payload.prerenderedAt = Date.now()
|
||||
@ -330,7 +331,7 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
|
||||
await payloadCache!.setItem(withoutTrailingSlash(url), renderPayloadResponse(ssrContext))
|
||||
}
|
||||
|
||||
if (process.env.NUXT_INLINE_STYLES && !islandContext) {
|
||||
if (process.env.NUXT_INLINE_STYLES && !isRenderingIsland) {
|
||||
const source = ssrContext.modules ?? ssrContext._registeredComponents
|
||||
if (source) {
|
||||
for (const id of await getEntryIds()) {
|
||||
@ -340,7 +341,7 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
|
||||
}
|
||||
|
||||
// Render inline styles
|
||||
const inlinedStyles = (process.env.NUXT_INLINE_STYLES || Boolean(islandContext))
|
||||
const inlinedStyles = (process.env.NUXT_INLINE_STYLES || isRenderingIsland)
|
||||
? await renderInlineStyles(ssrContext.modules ?? ssrContext._registeredComponents ?? [])
|
||||
: []
|
||||
|
||||
@ -349,7 +350,7 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
|
||||
// Setup head
|
||||
const { styles, scripts } = getRequestDependencies(ssrContext, renderer.rendererContext)
|
||||
// 1.Extracted payload preloading
|
||||
if (_PAYLOAD_EXTRACTION) {
|
||||
if (_PAYLOAD_EXTRACTION && !isRenderingIsland) {
|
||||
head.push({
|
||||
link: [
|
||||
process.env.NUXT_JSON_PAYLOADS
|
||||
@ -361,14 +362,18 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
|
||||
|
||||
// 2. Styles
|
||||
head.push({ style: inlinedStyles })
|
||||
head.push({
|
||||
link: Object.values(styles)
|
||||
.map(resource =>
|
||||
({ rel: 'stylesheet', href: renderer.rendererContext.buildAssetsURL(resource.file) })
|
||||
)
|
||||
}, headEntryOptions)
|
||||
if (!isRenderingIsland || import.meta.dev) {
|
||||
const link = []
|
||||
for (const style in styles) {
|
||||
const resource = styles[style]
|
||||
if (!import.meta.dev || (resource.file.includes('scoped') && !resource.file.includes('pages/'))) {
|
||||
link.push({ rel: 'stylesheet', href: renderer.rendererContext.buildAssetsURL(resource.file) })
|
||||
}
|
||||
}
|
||||
head.push({ link }, headEntryOptions)
|
||||
}
|
||||
|
||||
if (!NO_SCRIPTS) {
|
||||
if (!NO_SCRIPTS && !isRenderingIsland) {
|
||||
// 3. Resource Hints
|
||||
// TODO: add priorities based on Capo
|
||||
head.push({
|
||||
@ -395,7 +400,7 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
|
||||
}
|
||||
|
||||
// 5. Scripts
|
||||
if (!routeOptions.experimentalNoScripts) {
|
||||
if (!routeOptions.experimentalNoScripts && !isRenderingIsland) {
|
||||
head.push({
|
||||
script: Object.values(scripts).map(resource => (<Script> {
|
||||
type: resource.module ? 'module' : null,
|
||||
@ -411,7 +416,7 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
|
||||
|
||||
// Create render context
|
||||
const htmlContext: NuxtRenderHTMLContext = {
|
||||
island: Boolean(islandContext),
|
||||
island: isRenderingIsland,
|
||||
htmlAttrs: htmlAttrs ? [htmlAttrs] : [],
|
||||
head: normalizeChunks([headTags, ssrContext.styles]),
|
||||
bodyAttrs: bodyAttrs ? [bodyAttrs] : [],
|
||||
@ -424,16 +429,15 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
|
||||
await nitroApp.hooks.callHook('render:html', htmlContext, { event })
|
||||
|
||||
// Response for component islands
|
||||
if (process.env.NUXT_COMPONENT_ISLANDS && islandContext) {
|
||||
if (isRenderingIsland && islandContext) {
|
||||
const islandHead: NuxtIslandResponse['head'] = {
|
||||
link: [],
|
||||
style: []
|
||||
}
|
||||
for (const tag of await head.resolveTags()) {
|
||||
if (tag.tag === 'link' && tag.props.rel === 'stylesheet' && tag.props.href.includes('scoped') && !tag.props.href.includes('pages/')) {
|
||||
islandHead.link.push({ ...tag.props, key: 'island-link-' + hash(tag.props.href) })
|
||||
}
|
||||
if (tag.tag === 'style' && tag.innerHTML) {
|
||||
if (tag.tag === 'link') {
|
||||
islandHead.link.push({ key: 'island-link-' + hash(tag.props), ...tag.props })
|
||||
} else if (tag.tag === 'style' && tag.innerHTML) {
|
||||
islandHead.style.push({ key: 'island-style-' + hash(tag.innerHTML), innerHTML: tag.innerHTML })
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ describe.skipIf(process.env.SKIP_BUNDLE_SIZE === 'true' || process.env.ECOSYSTEM
|
||||
const serverDir = join(rootDir, '.output/server')
|
||||
|
||||
const serverStats = await analyzeSizes(['**/*.mjs', '!node_modules'], serverDir)
|
||||
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"200k"`)
|
||||
expect.soft(roundToKilobytes(serverStats.totalBytes)).toMatchInlineSnapshot(`"201k"`)
|
||||
|
||||
const modules = await analyzeSizes('node_modules/**/*', serverDir)
|
||||
expect.soft(roundToKilobytes(modules.totalBytes)).toMatchInlineSnapshot(`"1335k"`)
|
||||
|
Loading…
Reference in New Issue
Block a user