diff --git a/lib/app/index.js b/lib/app/index.js index 2e7fe7eab0..44375eeb88 100644 --- a/lib/app/index.js +++ b/lib/app/index.js @@ -113,6 +113,7 @@ async function createApp (ssrContext) { <% if(store) { %>store,<% } %> req: ssrContext ? ssrContext.req : undefined, res: ssrContext ? ssrContext.res : undefined, + beforeRenderFns: ssrContext ? ssrContext.beforeRenderFns : undefined }, app) <% plugins.filter(p => p.ssr).forEach(plugin => { %> diff --git a/lib/app/server.js b/lib/app/server.js index 30854eb407..11f011ea0b 100644 --- a/lib/app/server.js +++ b/lib/app/server.js @@ -45,27 +45,28 @@ export default async context => { // Create context.next for simulate next() of beforeEach() when wanted to redirect context.redirected = false context.next = createNext(context) - + context.beforeRenderFns = [] + const { app, router<%= (store ? ', store' : '') %> } = await createApp(context) const _app = new Vue(app) - + <% if (store) { %> // Add store to the context context.store = store <% } %> - + // Add route to the context context.route = router.currentRoute - + // Nuxt object context.nuxt = { layout: 'default', data: [], error: null<%= (store ? ', state: null' : '') %>, serverRendered: true } - + // Add meta infos context.meta = _app.$meta() - + // Error function context.error = _app.$options._nuxt.error.bind(_app) - + // Keep asyncData for each matched component in context context.asyncData = {} @@ -73,8 +74,8 @@ export default async context => { const ctx = getContext(context, app) <% if (isDev) { %>const s = isDev && Date.now()<% } %> - - // Resolve components + + // Resolve components let Components = [] try { Components = await Promise.all(getMatchedComponents(router.match(context.url)).map(Component => { @@ -118,7 +119,7 @@ export default async context => { layout = _app.setLayout(layout) // ...Set layout to __NUXT__ context.nuxt.layout = _app.layoutName - + // Call middleware (layout + pages) if (!context.nuxt.error) { midd = [] @@ -134,9 +135,9 @@ export default async context => { } return middleware[name] }) - + await middlewareSeries(midd, ctx) - + // If there is a redirect if (context.redirected) return noopApp() } @@ -161,11 +162,11 @@ export default async context => { // Call the 404 error by making the Components array empty Components = [] } - + // Call asyncData & fetch hooks on components matched by the route. let asyncDatas = await Promise.all(Components.map(Component => { let promises = [] - + // Call asyncData(context) if (Component.options.asyncData && typeof Component.options.asyncData === 'function') { let promise = promisify(Component.options.asyncData, ctx) @@ -189,7 +190,7 @@ export default async context => { return Promise.all(promises) })) - + // If no Components found, returns 404 if (!Components.length) { context.nuxt.error = context.error({ statusCode: 404, message: 'This page could not be found.' }) @@ -210,6 +211,8 @@ export default async context => { context.nuxt.state = store.state <% } %> + await Promise.all(context.beforeRenderFns.map((fn) => promisify(fn, { Components, nuxtState: context.nuxt }))) + // If no error, return main app if (!context.nuxt.error) { return _app @@ -220,6 +223,6 @@ export default async context => { context.nuxt.layout = layout || '' await _app.loadLayout(layout) _app.setLayout(layout) - + return _app } diff --git a/lib/app/utils.js b/lib/app/utils.js index 547f46b86a..1cbe23b0d9 100644 --- a/lib/app/utils.js +++ b/lib/app/utils.js @@ -104,6 +104,9 @@ export function getContext (context, app) { if (context.req) ctx.req = context.req if (context.res) ctx.res = context.res if (context.from) ctx.from = context.from + if (ctx.isServer && context.beforeRenderFns) { + ctx.beforeNuxtRender = (fn) => context.beforeRenderFns.push(fn) + } return ctx }