From 59600d8480f08f536e537e25d05c93b1e46a6161 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Thu, 21 Jul 2022 19:26:21 +0200 Subject: [PATCH 01/15] feat(nuxt): add `app:rendered` hook --- packages/nuxt/src/app/nuxt.ts | 4 +- .../nuxt/src/core/runtime/nitro/renderer.ts | 114 ++++++++++-------- 2 files changed, 69 insertions(+), 49 deletions(-) diff --git a/packages/nuxt/src/app/nuxt.ts b/packages/nuxt/src/app/nuxt.ts index fce05c322ce..c243a8a7b38 100644 --- a/packages/nuxt/src/app/nuxt.ts +++ b/packages/nuxt/src/app/nuxt.ts @@ -6,6 +6,8 @@ import type { RuntimeConfig } from '@nuxt/schema' import { getContext } from 'unctx' import type { SSRContext } from 'vue-bundle-renderer' import type { CompatibilityEvent } from 'h3' +// eslint-disable-next-line import/no-restricted-paths +import type { NuxtRenderContext } from '../core/runtime/nitro/renderer' const nuxtAppCtx = getContext('nuxt-app') @@ -23,7 +25,7 @@ export interface RuntimeNuxtHooks { 'app:created': (app: App) => HookResult 'app:beforeMount': (app: App) => HookResult 'app:mounted': (app: App) => HookResult - 'app:rendered': () => HookResult + 'app:rendered': (ctx: NuxtRenderContext) => HookResult 'app:redirected': () => HookResult 'app:suspense:resolve': (Component?: VNode) => HookResult 'app:error': (err: any) => HookResult diff --git a/packages/nuxt/src/core/runtime/nitro/renderer.ts b/packages/nuxt/src/core/runtime/nitro/renderer.ts index 3562c6cabe9..6a230ef7cec 100644 --- a/packages/nuxt/src/core/runtime/nitro/renderer.ts +++ b/packages/nuxt/src/core/runtime/nitro/renderer.ts @@ -2,31 +2,27 @@ import { createRenderer } from 'vue-bundle-renderer' import { eventHandler, useQuery } from 'h3' import devalue from '@nuxt/devalue' import { renderToString as _renderToString } from 'vue/server-renderer' - import type { NuxtApp } from '#app' // @ts-ignore -import { useRuntimeConfig } from '#internal/nitro' +import { useRuntimeConfig, useNitroApp } from '#internal/nitro' // @ts-ignore import { buildAssetsURL } from '#paths' // @ts-ignore import htmlTemplate from '#build/views/document.template.mjs' -type NuxtSSRContext = NuxtApp['ssrContext'] - -interface RenderResult { - html: any - renderResourceHints: () => string - renderStyles: () => string - renderScripts: () => string - meta?: Partial<{ - htmlAttrs?: string, - bodyAttrs: string, - headAttrs: string, - headTags: string, - bodyScriptsPrepend : string, - bodyScripts : string - }> +export type NuxtSSRContext = NuxtApp['ssrContext'] + +export interface NuxtRenderContext { + ssrContext: NuxtSSRContext + body: string + meta: { + htmlAttrs: string[] + head: string[] + bodyAttrs: string[] + bodyPreprend: string[] + bodyAppend: string[] + } } // @ts-ignore @@ -128,50 +124,68 @@ export default eventHandler(async (event) => { // Render app const renderer = (process.env.NUXT_NO_SSR || ssrContext.noSSR) ? await getSPARenderer() : await getSSRRenderer() - const rendered = await renderer.renderToString(ssrContext).catch((e) => { - if (!ssrError) { throw e } - }) as RenderResult - - // If we error on rendering error page, we bail out and directly return to the error handler - if (!rendered) { return } + const _rendered = await renderer.renderToString(ssrContext).catch((err) => { + if (!ssrError) { throw err } + }) - if (event.res.writableEnded) { + // Handle errors + if (!_rendered) { return } - - // Handle errors if (ssrContext.error && !ssrError) { throw ssrContext.error } - if (ssrContext.nuxt?.hooks) { - await ssrContext.nuxt.hooks.callHook('app:rendered') + // Render meta + const renderedMeta = await ssrContext.renderMeta() + + // Create render conrtext + const rendered: NuxtRenderContext = { + ssrContext, + body: _rendered.html, // TODO: Rename to _rendered.body in next vue-bundle-renderer + meta: { + htmlAttrs: [renderedMeta.htmlAttrs || ''], + bodyAttrs: [renderedMeta.bodyAttrs || ''], + head: [ + renderedMeta.headTags || '', + _rendered.renderResourceHints(), + _rendered.renderStyles(), + ssrContext.styles || '' + ], + bodyPreprend: [ + renderedMeta.bodyScriptsPrepend, + ssrContext.teleports?.body + ], + bodyAppend: [ + ``, + _rendered.renderScripts(), + renderedMeta.bodyScripts || '' + ] + } } - const html = await renderHTML(ssrContext.payload, rendered, ssrContext) + // Allow hooking into the rendered result + const nitroApp = useNitroApp() + await ssrContext.nuxt.hooks.callHook('app:rendered', rendered) + await nitroApp.hooks.callHook('nuxt:app:rendered', rendered) + + // Construct HTML template + const html = htmlTemplate({ + HTML_ATTRS: joinMeta(rendered.meta.htmlAttrs), + HEAD_ATTRS: '', // TODO: Remove? + HEAD: joinMeta(rendered.meta.head), + BODY_ATTRS: joinMeta(rendered.meta.bodyAttrs), + BODY_PREPEND: joinMeta(rendered.meta.bodyPreprend), + APP: rendered.body + joinMeta(rendered.meta.bodyAppend) + }) + await nitroApp.hooks.callHook('nuxt:app:rendered:html', { html }) + + // Send HTML response + if (event.res.writableEnded) { return } event.res.setHeader('Content-Type', 'text/html;charset=UTF-8') return html }) -async function renderHTML (payload: any, rendered: RenderResult, ssrContext: NuxtSSRContext) { - const state = `` - - rendered.meta = rendered.meta || {} - if (ssrContext.renderMeta) { - Object.assign(rendered.meta, await ssrContext.renderMeta()) - } - - return htmlTemplate({ - HTML_ATTRS: (rendered.meta.htmlAttrs || ''), - HEAD_ATTRS: (rendered.meta.headAttrs || ''), - HEAD: (rendered.meta.headTags || '') + - rendered.renderResourceHints() + rendered.renderStyles() + (ssrContext.styles || ''), - BODY_ATTRS: (rendered.meta.bodyAttrs || ''), - BODY_PREPEND: (ssrContext.teleports?.body || ''), - APP: (rendered.meta.bodyScriptsPrepend || '') + rendered.html + state + rendered.renderScripts() + (rendered.meta.bodyScripts || '') - }) -} - function lazyCachedFunction (fn: () => Promise): () => Promise { let res: Promise | null = null return () => { @@ -181,3 +195,7 @@ function lazyCachedFunction (fn: () => Promise): () => Promise { return res } } + +function joinMeta (meta: string[]) { + return meta.filter(Boolean).map(i => i.trim()).join('') +} From eb133ca92709c25523132f61d27b15f2c4a7ff64 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Thu, 21 Jul 2022 19:42:12 +0200 Subject: [PATCH 02/15] normalize meta in initial context --- .../nuxt/src/core/runtime/nitro/renderer.ts | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/nuxt/src/core/runtime/nitro/renderer.ts b/packages/nuxt/src/core/runtime/nitro/renderer.ts index 6a230ef7cec..d299b7e8b2b 100644 --- a/packages/nuxt/src/core/runtime/nitro/renderer.ts +++ b/packages/nuxt/src/core/runtime/nitro/renderer.ts @@ -144,23 +144,23 @@ export default eventHandler(async (event) => { ssrContext, body: _rendered.html, // TODO: Rename to _rendered.body in next vue-bundle-renderer meta: { - htmlAttrs: [renderedMeta.htmlAttrs || ''], - bodyAttrs: [renderedMeta.bodyAttrs || ''], - head: [ - renderedMeta.headTags || '', + htmlAttrs: normalizeMeta([renderedMeta.htmlAttrs]), + bodyAttrs: normalizeMeta([renderedMeta.bodyAttrs]), + head: normalizeMeta([ + renderedMeta.headTags, _rendered.renderResourceHints(), _rendered.renderStyles(), - ssrContext.styles || '' - ], - bodyPreprend: [ + ssrContext.styles + ]), + bodyPreprend: normalizeMeta([ renderedMeta.bodyScriptsPrepend, ssrContext.teleports?.body - ], - bodyAppend: [ + ]), + bodyAppend: normalizeMeta([ ``, _rendered.renderScripts(), - renderedMeta.bodyScripts || '' - ] + renderedMeta.bodyScripts + ]) } } @@ -196,6 +196,10 @@ function lazyCachedFunction (fn: () => Promise): () => Promise { } } +function normalizeMeta (meta: string[]) { + return meta.filter(Boolean).map(i => i.trim()) +} + function joinMeta (meta: string[]) { - return meta.filter(Boolean).map(i => i.trim()).join('') + return meta.join('') } From 41887b43dc33df4d59a1a92915856ec346fb4afc Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Thu, 21 Jul 2022 19:53:58 +0200 Subject: [PATCH 03/15] refactor: inline html template --- .../nuxt/src/core/runtime/nitro/renderer.ts | 24 +++++++++++-------- packages/nuxt/src/core/templates.ts | 20 ---------------- 2 files changed, 14 insertions(+), 30 deletions(-) diff --git a/packages/nuxt/src/core/runtime/nitro/renderer.ts b/packages/nuxt/src/core/runtime/nitro/renderer.ts index d299b7e8b2b..8f7ceaa7a6d 100644 --- a/packages/nuxt/src/core/runtime/nitro/renderer.ts +++ b/packages/nuxt/src/core/runtime/nitro/renderer.ts @@ -8,8 +8,6 @@ import type { NuxtApp } from '#app' import { useRuntimeConfig, useNitroApp } from '#internal/nitro' // @ts-ignore import { buildAssetsURL } from '#paths' -// @ts-ignore -import htmlTemplate from '#build/views/document.template.mjs' export type NuxtSSRContext = NuxtApp['ssrContext'] @@ -170,14 +168,7 @@ export default eventHandler(async (event) => { await nitroApp.hooks.callHook('nuxt:app:rendered', rendered) // Construct HTML template - const html = htmlTemplate({ - HTML_ATTRS: joinMeta(rendered.meta.htmlAttrs), - HEAD_ATTRS: '', // TODO: Remove? - HEAD: joinMeta(rendered.meta.head), - BODY_ATTRS: joinMeta(rendered.meta.bodyAttrs), - BODY_PREPEND: joinMeta(rendered.meta.bodyPreprend), - APP: rendered.body + joinMeta(rendered.meta.bodyAppend) - }) + const html = renderHTMLDocument(rendered) await nitroApp.hooks.callHook('nuxt:app:rendered:html', { html }) // Send HTML response @@ -203,3 +194,16 @@ function normalizeMeta (meta: string[]) { function joinMeta (meta: string[]) { return meta.join('') } + +function renderHTMLDocument (rendered: NuxtRenderContext) { + return ` + + + ${joinMeta(rendered.meta.head)} + +${joinMeta(rendered.meta.bodyPreprend)} +${rendered.body} + ${joinMeta(rendered.meta.bodyAppend)} + +` +} diff --git a/packages/nuxt/src/core/templates.ts b/packages/nuxt/src/core/templates.ts index 061e9572a33..7357228242a 100644 --- a/packages/nuxt/src/core/templates.ts +++ b/packages/nuxt/src/core/templates.ts @@ -70,26 +70,6 @@ export const serverPluginTemplate = { } } -export const appViewTemplate = { - filename: 'views/document.template.mjs', - write: true, - getContents () { - return `export default (params) => \` - - - - \${params.HEAD} - - -\${params.BODY_PREPEND} - \${params.APP} - - -\` -` - } -} - export const pluginsDeclaration = { filename: 'types/plugins.d.ts', getContents: (ctx: TemplateContext) => { From 2472eb3719d5cc2824e2c4406ffba366e11bd405 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Mon, 25 Jul 2022 14:16:36 +0200 Subject: [PATCH 04/15] refactor: move body to ctx.html --- .../nuxt/src/core/runtime/nitro/renderer.ts | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/packages/nuxt/src/core/runtime/nitro/renderer.ts b/packages/nuxt/src/core/runtime/nitro/renderer.ts index 7b45f9f6c12..0f521cd1a1a 100644 --- a/packages/nuxt/src/core/runtime/nitro/renderer.ts +++ b/packages/nuxt/src/core/runtime/nitro/renderer.ts @@ -13,12 +13,12 @@ export type NuxtSSRContext = NuxtApp['ssrContext'] export interface NuxtRenderContext { ssrContext: NuxtSSRContext - body: string - meta: { + html: { htmlAttrs: string[] head: string[] bodyAttrs: string[] bodyPreprend: string[] + body: string[] bodyAppend: string[] } } @@ -144,24 +144,27 @@ export default eventHandler(async (event) => { // Create render conrtext const rendered: NuxtRenderContext = { ssrContext, - body: _rendered.html, // TODO: Rename to _rendered.body in next vue-bundle-renderer - meta: { + html: { htmlAttrs: normalizeMeta([renderedMeta.htmlAttrs]), - bodyAttrs: normalizeMeta([renderedMeta.bodyAttrs]), head: normalizeMeta([ renderedMeta.headTags, _rendered.renderResourceHints(), _rendered.renderStyles(), ssrContext.styles ]), + bodyAttrs: normalizeMeta([renderedMeta.bodyAttrs]), bodyPreprend: normalizeMeta([ renderedMeta.bodyScriptsPrepend, ssrContext.teleports?.body ]), + body: [ + // TODO: Rename to _rendered.body in next vue-bundle-renderer + _rendered.html + ], bodyAppend: normalizeMeta([ - ``, - _rendered.renderScripts(), - renderedMeta.bodyScripts + ``, + _rendered.renderScripts(), + renderedMeta.bodyScripts ]) } } @@ -201,13 +204,13 @@ function joinMeta (meta: string[]) { function renderHTMLDocument (rendered: NuxtRenderContext) { return ` - + - ${joinMeta(rendered.meta.head)} + ${joinMeta(rendered.html.head)} -${joinMeta(rendered.meta.bodyPreprend)} -${rendered.body} - ${joinMeta(rendered.meta.bodyAppend)} +${joinMeta(rendered.html.bodyPreprend)} +${joinMeta(rendered.html.body)} + ${joinMeta(rendered.html.bodyAppend)} ` } From 823c33f535e6aa3127f2faa17e0a780f737b0507 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Mon, 25 Jul 2022 14:25:08 +0200 Subject: [PATCH 05/15] fix: add missing refactor --- packages/nuxt/src/core/runtime/nitro/renderer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nuxt/src/core/runtime/nitro/renderer.ts b/packages/nuxt/src/core/runtime/nitro/renderer.ts index 0f521cd1a1a..197579e56aa 100644 --- a/packages/nuxt/src/core/runtime/nitro/renderer.ts +++ b/packages/nuxt/src/core/runtime/nitro/renderer.ts @@ -204,7 +204,7 @@ function joinMeta (meta: string[]) { function renderHTMLDocument (rendered: NuxtRenderContext) { return ` - + ${joinMeta(rendered.html.head)} From 280611052514d20f345460ec73eba25dd399ab47 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Mon, 25 Jul 2022 14:25:17 +0200 Subject: [PATCH 06/15] fix typo --- packages/nuxt/src/core/runtime/nitro/renderer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nuxt/src/core/runtime/nitro/renderer.ts b/packages/nuxt/src/core/runtime/nitro/renderer.ts index 197579e56aa..0e5cfdb05b5 100644 --- a/packages/nuxt/src/core/runtime/nitro/renderer.ts +++ b/packages/nuxt/src/core/runtime/nitro/renderer.ts @@ -204,7 +204,7 @@ function joinMeta (meta: string[]) { function renderHTMLDocument (rendered: NuxtRenderContext) { return ` - + ${joinMeta(rendered.html.head)} From 147969f6b13bdb070379fa0cf3e59fb50333f3a3 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Mon, 25 Jul 2022 14:27:59 +0200 Subject: [PATCH 07/15] fix joiners --- packages/nuxt/src/core/runtime/nitro/renderer.ts | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/nuxt/src/core/runtime/nitro/renderer.ts b/packages/nuxt/src/core/runtime/nitro/renderer.ts index 0e5cfdb05b5..369c50766ea 100644 --- a/packages/nuxt/src/core/runtime/nitro/renderer.ts +++ b/packages/nuxt/src/core/runtime/nitro/renderer.ts @@ -198,19 +198,18 @@ function normalizeMeta (meta: string[]) { return meta.filter(Boolean).map(i => i.trim()) } -function joinMeta (meta: string[]) { +function joinTags (meta: string[]) { return meta.join('') } +function joinMeta (meta: string[]) { + return meta.join(' ') +} + function renderHTMLDocument (rendered: NuxtRenderContext) { return ` - - ${joinMeta(rendered.html.head)} - -${joinMeta(rendered.html.bodyPreprend)} -${joinMeta(rendered.html.body)} - ${joinMeta(rendered.html.bodyAppend)} - +${joinTags(rendered.html.head)} +${joinTags(rendered.html.bodyPreprend)}${joinTags(rendered.html.body)}${joinTags(rendered.html.bodyAppend)} ` } From d295bc8f0e25a72659bc56c53a558a19022b97ca Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Mon, 25 Jul 2022 14:28:18 +0200 Subject: [PATCH 08/15] better name for joinAttrs --- packages/nuxt/src/core/runtime/nitro/renderer.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/nuxt/src/core/runtime/nitro/renderer.ts b/packages/nuxt/src/core/runtime/nitro/renderer.ts index 369c50766ea..8795b2c82d3 100644 --- a/packages/nuxt/src/core/runtime/nitro/renderer.ts +++ b/packages/nuxt/src/core/runtime/nitro/renderer.ts @@ -202,14 +202,14 @@ function joinTags (meta: string[]) { return meta.join('') } -function joinMeta (meta: string[]) { +function joinAttrs (meta: string[]) { return meta.join(' ') } function renderHTMLDocument (rendered: NuxtRenderContext) { return ` - + ${joinTags(rendered.html.head)} -${joinTags(rendered.html.bodyPreprend)}${joinTags(rendered.html.body)}${joinTags(rendered.html.bodyAppend)} +${joinTags(rendered.html.bodyPreprend)}${joinTags(rendered.html.body)}${joinTags(rendered.html.bodyAppend)} ` } From 93ee5225c6476c62485483d92b6ac4a639b4efa6 Mon Sep 17 00:00:00 2001 From: pooya parsa Date: Mon, 25 Jul 2022 16:55:20 +0200 Subject: [PATCH 09/15] Update packages/nuxt/src/core/runtime/nitro/renderer.ts Co-authored-by: Daniel Roe --- packages/nuxt/src/core/runtime/nitro/renderer.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/nuxt/src/core/runtime/nitro/renderer.ts b/packages/nuxt/src/core/runtime/nitro/renderer.ts index 8795b2c82d3..a10797991d3 100644 --- a/packages/nuxt/src/core/runtime/nitro/renderer.ts +++ b/packages/nuxt/src/core/runtime/nitro/renderer.ts @@ -198,12 +198,12 @@ function normalizeMeta (meta: string[]) { return meta.filter(Boolean).map(i => i.trim()) } -function joinTags (meta: string[]) { - return meta.join('') +function joinTags (tags: string[]) { + return tags.join('') } -function joinAttrs (meta: string[]) { - return meta.join(' ') +function joinAttrs (chunks: string[]) { + return chunks.join(' ') } function renderHTMLDocument (rendered: NuxtRenderContext) { From 57b0b1beec33e4712bd46f7e450bd9621b33b5b5 Mon Sep 17 00:00:00 2001 From: pooya parsa Date: Mon, 25 Jul 2022 17:22:11 +0200 Subject: [PATCH 10/15] Update packages/nuxt/src/core/runtime/nitro/renderer.ts Co-authored-by: Daniel Roe --- packages/nuxt/src/core/runtime/nitro/renderer.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nuxt/src/core/runtime/nitro/renderer.ts b/packages/nuxt/src/core/runtime/nitro/renderer.ts index a10797991d3..ac53084cf17 100644 --- a/packages/nuxt/src/core/runtime/nitro/renderer.ts +++ b/packages/nuxt/src/core/runtime/nitro/renderer.ts @@ -194,8 +194,8 @@ function lazyCachedFunction (fn: () => Promise): () => Promise { } } -function normalizeMeta (meta: string[]) { - return meta.filter(Boolean).map(i => i.trim()) +function normalizeChunks (chunks: string[]) { + return chunks.filter(Boolean).map(i => i.trim()) } function joinTags (tags: string[]) { From 6bb44e96e105bc35661083a4d5d0d07d762fcaf6 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Mon, 25 Jul 2022 16:27:18 +0100 Subject: [PATCH 11/15] Update packages/nuxt/src/core/runtime/nitro/renderer.ts --- packages/nuxt/src/core/runtime/nitro/renderer.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/nuxt/src/core/runtime/nitro/renderer.ts b/packages/nuxt/src/core/runtime/nitro/renderer.ts index ac53084cf17..23201200417 100644 --- a/packages/nuxt/src/core/runtime/nitro/renderer.ts +++ b/packages/nuxt/src/core/runtime/nitro/renderer.ts @@ -145,15 +145,15 @@ export default eventHandler(async (event) => { const rendered: NuxtRenderContext = { ssrContext, html: { - htmlAttrs: normalizeMeta([renderedMeta.htmlAttrs]), - head: normalizeMeta([ + htmlAttrs: normalizeChunks([renderedMeta.htmlAttrs]), + head: normalizeChunks([ renderedMeta.headTags, _rendered.renderResourceHints(), _rendered.renderStyles(), ssrContext.styles ]), - bodyAttrs: normalizeMeta([renderedMeta.bodyAttrs]), - bodyPreprend: normalizeMeta([ + bodyAttrs: normalizeChunks([renderedMeta.bodyAttrs]), + bodyPreprend: normalizeChunks([ renderedMeta.bodyScriptsPrepend, ssrContext.teleports?.body ]), From 5f903628f6dfa5ad8594b8574eed7e006c52b629 Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Mon, 25 Jul 2022 16:27:51 +0100 Subject: [PATCH 12/15] Update packages/nuxt/src/core/runtime/nitro/renderer.ts --- packages/nuxt/src/core/runtime/nitro/renderer.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nuxt/src/core/runtime/nitro/renderer.ts b/packages/nuxt/src/core/runtime/nitro/renderer.ts index 23201200417..9c5da2beb7e 100644 --- a/packages/nuxt/src/core/runtime/nitro/renderer.ts +++ b/packages/nuxt/src/core/runtime/nitro/renderer.ts @@ -161,7 +161,7 @@ export default eventHandler(async (event) => { // TODO: Rename to _rendered.body in next vue-bundle-renderer _rendered.html ], - bodyAppend: normalizeMeta([ + bodyAppend: normalizeChunks([ ``, _rendered.renderScripts(), renderedMeta.bodyScripts From fd04c7cb781e560916fd4771fcc237e558732b17 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Wed, 27 Jul 2022 11:27:02 +0200 Subject: [PATCH 13/15] feat: `app:response` hook --- .../nuxt/src/core/runtime/nitro/renderer.ts | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/packages/nuxt/src/core/runtime/nitro/renderer.ts b/packages/nuxt/src/core/runtime/nitro/renderer.ts index 9c5da2beb7e..9bd64e9f997 100644 --- a/packages/nuxt/src/core/runtime/nitro/renderer.ts +++ b/packages/nuxt/src/core/runtime/nitro/renderer.ts @@ -174,14 +174,35 @@ export default eventHandler(async (event) => { await ssrContext.nuxt.hooks.callHook('app:rendered', rendered) await nitroApp.hooks.callHook('nuxt:app:rendered', rendered) - // Construct HTML template - const html = renderHTMLDocument(rendered) - await nitroApp.hooks.callHook('nuxt:app:rendered:html', { html }) + // Construct HTML response + const response = { + body: renderHTMLDocument(rendered), + statusCode: null, + statusMessage: null, + headers: { + 'Content-Type': 'text/html;charset=UTF-8', + 'X-Powered-By': 'Nuxt' + } + } + + // Allow extending the response + await nitroApp.hooks.callHook('nuxt:app:response', { response }) // Send HTML response - if (event.res.writableEnded) { return } - event.res.setHeader('Content-Type', 'text/html;charset=UTF-8') - return html + if (!event.res.headersSent) { + for (const header in response.headers) { + event.res.setHeader(header, response.headers[header]) + } + if (response.statusCode) { + event.res.statusCode = response.statusCode + } + if (response.statusMessage) { + event.res.statusMessage = response.statusMessage + } + } + if (!event.res.writableEnded) { + event.res.end(response.body) + } }) function lazyCachedFunction (fn: () => Promise): () => Promise { From ea3f0f1d65f3f6388be5008523d0daac0d90566a Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Wed, 27 Jul 2022 11:33:27 +0200 Subject: [PATCH 14/15] inherit statusCode/statusMessage from event --- packages/nuxt/src/core/runtime/nitro/renderer.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/nuxt/src/core/runtime/nitro/renderer.ts b/packages/nuxt/src/core/runtime/nitro/renderer.ts index 9bd64e9f997..f300e64d8c1 100644 --- a/packages/nuxt/src/core/runtime/nitro/renderer.ts +++ b/packages/nuxt/src/core/runtime/nitro/renderer.ts @@ -177,8 +177,8 @@ export default eventHandler(async (event) => { // Construct HTML response const response = { body: renderHTMLDocument(rendered), - statusCode: null, - statusMessage: null, + statusCode: event.res.statusCode, + statusMessage: event.res.statusMessage, headers: { 'Content-Type': 'text/html;charset=UTF-8', 'X-Powered-By': 'Nuxt' @@ -193,12 +193,8 @@ export default eventHandler(async (event) => { for (const header in response.headers) { event.res.setHeader(header, response.headers[header]) } - if (response.statusCode) { - event.res.statusCode = response.statusCode - } - if (response.statusMessage) { - event.res.statusMessage = response.statusMessage - } + event.res.statusCode = response.statusCode + event.res.statusMessage = response.statusMessage } if (!event.res.writableEnded) { event.res.end(response.body) From 0e1c1c13db461706e579f2889e2f757fa596eff0 Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Wed, 27 Jul 2022 11:49:02 +0200 Subject: [PATCH 15/15] add NuxtRenderResponse --- packages/nuxt/src/core/runtime/nitro/renderer.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/nuxt/src/core/runtime/nitro/renderer.ts b/packages/nuxt/src/core/runtime/nitro/renderer.ts index f300e64d8c1..28eb2ae885a 100644 --- a/packages/nuxt/src/core/runtime/nitro/renderer.ts +++ b/packages/nuxt/src/core/runtime/nitro/renderer.ts @@ -23,6 +23,13 @@ export interface NuxtRenderContext { } } +export interface NuxtRenderResponse { + body: string, + statusCode: number, + statusMessage?: string, + headers: Record +} + // @ts-ignore const getClientManifest = () => import('#build/dist/server/client.manifest.mjs') .then(r => r.default || r) @@ -175,7 +182,7 @@ export default eventHandler(async (event) => { await nitroApp.hooks.callHook('nuxt:app:rendered', rendered) // Construct HTML response - const response = { + const response: NuxtRenderResponse = { body: renderHTMLDocument(rendered), statusCode: event.res.statusCode, statusMessage: event.res.statusMessage,