mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-26 23:52:06 +00:00
feat(vue-renderer): support prepend/append body tags during ssr for all allowed tag types (#6134)
This commit is contained in:
parent
52b98abdd8
commit
df424e56cb
@ -1,6 +1,5 @@
|
||||
import { extname } from 'path'
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
import Vue from 'vue'
|
||||
import VueMeta from 'vue-meta'
|
||||
import { createRenderer } from 'vue-server-renderer'
|
||||
import LRU from 'lru-cache'
|
||||
@ -13,29 +12,19 @@ export default class SPARenderer extends BaseRenderer {
|
||||
|
||||
this.cache = new LRU()
|
||||
|
||||
// Add VueMeta to Vue (this is only for SPA mode)
|
||||
// See app/index.js
|
||||
Vue.use(VueMeta, {
|
||||
this.vueMetaConfig = {
|
||||
keyName: 'head',
|
||||
attribute: 'data-n-head',
|
||||
ssrAttribute: 'data-n-head-ssr',
|
||||
ssrAppId: '1',
|
||||
tagIDKeyName: 'hid'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
createRenderer () {
|
||||
return createRenderer()
|
||||
}
|
||||
|
||||
async getMeta () {
|
||||
const vm = new Vue({
|
||||
render: h => h(), // Render empty html tag
|
||||
head: this.options.head || {}
|
||||
})
|
||||
await this.vueRenderer.renderToString(vm)
|
||||
return vm.$meta().inject()
|
||||
}
|
||||
|
||||
async render (renderContext) {
|
||||
const { url = '/', req = {}, _generate } = renderContext
|
||||
const modernMode = this.options.modern
|
||||
@ -54,11 +43,19 @@ export default class SPARenderer extends BaseRenderer {
|
||||
HEAD_ATTRS: '',
|
||||
BODY_ATTRS: '',
|
||||
HEAD: '',
|
||||
BODY_SCRIPTS_PREPEND: '',
|
||||
BODY_SCRIPTS: ''
|
||||
}
|
||||
|
||||
// Get vue-meta context
|
||||
const m = await this.getMeta()
|
||||
let head
|
||||
if (typeof this.options.head === 'function') {
|
||||
head = this.options.head()
|
||||
} else {
|
||||
head = this.options.head
|
||||
}
|
||||
|
||||
const m = VueMeta.generate(head || {}, this.vueMetaConfig)
|
||||
|
||||
// HTML_ATTRS
|
||||
meta.HTML_ATTRS = m.htmlAttrs.text()
|
||||
@ -78,11 +75,23 @@ export default class SPARenderer extends BaseRenderer {
|
||||
m.script.text() +
|
||||
m.noscript.text()
|
||||
|
||||
// BODY_SCRIPTS
|
||||
meta.BODY_SCRIPTS = m.script.text({ body: true }) + m.noscript.text({ body: true })
|
||||
// BODY_SCRIPTS (PREPEND)
|
||||
meta.BODY_SCRIPTS_PREPEND =
|
||||
m.meta.text({ pbody: true }) +
|
||||
m.link.text({ pbody: true }) +
|
||||
m.style.text({ pbody: true }) +
|
||||
m.script.text({ pbody: true }) +
|
||||
m.noscript.text({ pbody: true })
|
||||
|
||||
// BODY_SCRIPTS (APPEND)
|
||||
meta.BODY_SCRIPTS =
|
||||
m.meta.text({ body: true }) +
|
||||
m.link.text({ body: true }) +
|
||||
m.style.text({ body: true }) +
|
||||
m.script.text({ body: true }) +
|
||||
m.noscript.text({ body: true })
|
||||
|
||||
// Resources Hints
|
||||
|
||||
meta.resourceHints = ''
|
||||
|
||||
const { resources: { modernManifest, clientManifest } } = this.serverContext
|
||||
@ -131,7 +140,7 @@ export default class SPARenderer extends BaseRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
const APP = `<div id="${this.serverContext.globals.id}">${this.serverContext.resources.loadingHTML}</div>${meta.BODY_SCRIPTS}`
|
||||
const APP = `${meta.BODY_SCRIPTS_PREPEND}<div id="${this.serverContext.globals.id}">${this.serverContext.resources.loadingHTML}</div>${meta.BODY_SCRIPTS}`
|
||||
|
||||
// Prepare template params
|
||||
const templateParams = {
|
||||
|
@ -109,6 +109,17 @@ export default class SSRRenderer extends BaseRenderer {
|
||||
// Inject styles
|
||||
HEAD += renderContext.renderStyles()
|
||||
|
||||
const BODY_PREPEND =
|
||||
m.meta.text({ pbody: true }) +
|
||||
m.link.text({ pbody: true }) +
|
||||
m.style.text({ pbody: true }) +
|
||||
m.script.text({ pbody: true }) +
|
||||
m.noscript.text({ pbody: true })
|
||||
|
||||
if (BODY_PREPEND) {
|
||||
APP = `${BODY_PREPEND}${APP}`
|
||||
}
|
||||
|
||||
// Serialize state
|
||||
const serializedSession = `window.${this.serverContext.globals.context}=${devalue(renderContext.nuxt)};`
|
||||
if (shouldInjectScripts) {
|
||||
@ -140,12 +151,17 @@ export default class SSRRenderer extends BaseRenderer {
|
||||
if (shouldInjectScripts) {
|
||||
APP += this.renderScripts(renderContext)
|
||||
}
|
||||
|
||||
// Append body scripts
|
||||
APP += m.meta.text({ body: true })
|
||||
APP += m.link.text({ body: true })
|
||||
APP += m.style.text({ body: true })
|
||||
APP += m.script.text({ body: true })
|
||||
APP += m.noscript.text({ body: true })
|
||||
|
||||
// Template params
|
||||
const templateParams = {
|
||||
HTML_ATTRS: 'data-n-head-ssr ' + m.htmlAttrs.text(),
|
||||
HTML_ATTRS: m.htmlAttrs.text(true /* addSrrAttribute */),
|
||||
HEAD_ATTRS: m.headAttrs.text(),
|
||||
BODY_ATTRS: m.bodyAttrs.text(),
|
||||
HEAD,
|
||||
|
Loading…
Reference in New Issue
Block a user