Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(vue-app): context.beforeSerialize method #9332

Merged
merged 14 commits into from Jun 4, 2021
2 changes: 2 additions & 0 deletions packages/types/app/index.d.ts
Expand Up @@ -72,6 +72,7 @@ export interface Context {
redirected: boolean
next: NextFunction
beforeRenderFns: Array<() => any>
beforeRenderHooks: Array<() => any>
fetchCounters: Record<string, number>
nuxt: {
layout: string
Expand All @@ -87,6 +88,7 @@ export interface Context {
error(params: NuxtError): void
nuxtState: NuxtState
beforeNuxtRender(fn: (params: { Components: VueRouter['getMatchedComponents'], nuxtState: NuxtState }) => void): void
beforeRender(fn: (params: { Components: VueRouter['getMatchedComponents'], nuxtState: NuxtState }) => void): void
enablePreview?: (previewData?: Record<string, any>) => void
$preview?: Record<string, any>
}
Expand Down
1 change: 1 addition & 0 deletions packages/vue-app/template/index.js
Expand Up @@ -183,6 +183,7 @@ async function createApp(ssrContext, config = {}) {
req: ssrContext ? ssrContext.req : undefined,
res: ssrContext ? ssrContext.res : undefined,
beforeRenderFns: ssrContext ? ssrContext.beforeRenderFns : undefined,
beforeRenderHooks: ssrContext ? ssrContext.beforeRenderHooks : undefined,
ssrContext
})

Expand Down
15 changes: 11 additions & 4 deletions packages/vue-app/template/server.js
Expand Up @@ -83,8 +83,10 @@ export default async (ssrContext) => {
// Create ssrContext.next for simulate next() of beforeEach() when wanted to redirect
ssrContext.redirected = false
ssrContext.next = createNext(ssrContext)
// Used for beforeNuxtRender({ Components, nuxtState })
// deprecated: Used for beforeNuxtRender({ Components, nuxtState })
ssrContext.beforeRenderFns = []
// for beforeRender({ Components, nuxtState })
ssrContext.beforeRenderHooks = []
// Nuxt object (window.{{globals.context}}, defaults to window.__NUXT__)
ssrContext.nuxt = { <% if (features.layouts) { %>layout: 'default', <% } %>data: [], <% if (features.fetch) { %>fetch: {}, <% } %>error: null<%= (store ? ', state: null' : '') %>, serverRendered: true, routePath: '' }
<% if (features.fetch) { %>
Expand Down Expand Up @@ -118,18 +120,23 @@ export default async (ssrContext) => {
<% } %>

const beforeRender = async () => {
// Call beforeNuxtRender() methods
// Deprecated: Call beforeNuxtRender() methods
await Promise.all(ssrContext.beforeRenderFns.map(fn => promisify(fn, { Components, nuxtState: ssrContext.nuxt })))
<% if (store) { %>

ssrContext.rendered = () => {
// Call beforeRender() hooks
ssrContext.beforeRenderHooks.forEach(fn => fn({ Components, nuxtState: ssrContext.nuxt }))

<% if (store) { %>
// Add the state from the vuex store
ssrContext.nuxt.state = store.state
<% } %>

<% if (isFullStatic && store) { %>
// Stop recording store mutations
ssrContext.unsetMutationObserver()
<% } %>
}
<% } %>
}

const renderErrorPage = async () => {
Expand Down
6 changes: 5 additions & 1 deletion packages/vue-app/template/utils.js
Expand Up @@ -258,7 +258,11 @@ export async function setContext (app, context) {
}
}
if (process.server) {
app.context.beforeNuxtRender = fn => context.beforeRenderFns.push(fn)
app.context.beforeNuxtRender = fn => {
console.warn('`context.beforeNuxtRender(fn)` is deprecated in favour of `context.beforeRender(fn)`. The function updating the `nuxtState` has to be synchronous. Learn more on https://nuxtjs.org/docs/2.x/internals-glossary/context#beforenuxtrender')
Atinux marked this conversation as resolved.
Show resolved Hide resolved
context.beforeRenderFns.push(fn)
}
app.context.beforeRender = fn => context.beforeRenderHooks.push(fn)
Atinux marked this conversation as resolved.
Show resolved Hide resolved
}
if (process.client) {
app.context.nuxtState = window.<%= globals.context %>
Expand Down
12 changes: 9 additions & 3 deletions test/dev/basic.ssr.test.js
Expand Up @@ -201,10 +201,16 @@ describe('basic ssr', () => {
})
})

test('/special-state -> check window.__NUXT__.test = true', async () => {
const window = await nuxt.server.renderAndGetWindow(url('/special-state'))
test('/before-nuxt-render -> check window.__NUXT__.beforeNuxtRender = true', async () => {
const window = await nuxt.server.renderAndGetWindow(url('/before-nuxt-render'))
expect(window.document.title).toBe('Nuxt')
expect(window.__NUXT__.test).toBe(true)
expect(window.__NUXT__.beforeNuxtRender).toBe(true)
})

test('/before-render -> check window.__NUXT__.beforeRender = true', async () => {
const window = await nuxt.server.renderAndGetWindow(url('/before-render'))
expect(window.document.title).toBe('Nuxt')
expect(window.__NUXT__.beforeRender).toBe(true)
})

test('/error', async () => {
Expand Down
Expand Up @@ -7,7 +7,7 @@ export default {
middleware ({ beforeNuxtRender }) {
if (process.server) {
beforeNuxtRender(({ nuxtState }) => {
nuxtState.test = true
nuxtState.beforeNuxtRender = true
})
}
}
Expand Down
26 changes: 26 additions & 0 deletions test/fixtures/basic/pages/before-render.vue
@@ -0,0 +1,26 @@
<template>
<div>
<h1>Special state in `window.__NUXT__`</h1>
<client-only><pre>{{ nuxtState }}</pre></client-only>
</div>
</template>

<script>
export default {
data () {
return {
nuxtState: null
}
},
fetch () {
if (process.server) {
this.$root.context.beforeRender(({ nuxtState }) => {
nuxtState.beforeRender = true
})
}
},
beforeMount () {
this.nuxtState = window.__NUXT__
}
}
</script>