mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-27 08:02:01 +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 { extname } from 'path'
|
||||||
import cloneDeep from 'lodash/cloneDeep'
|
import cloneDeep from 'lodash/cloneDeep'
|
||||||
import Vue from 'vue'
|
|
||||||
import VueMeta from 'vue-meta'
|
import VueMeta from 'vue-meta'
|
||||||
import { createRenderer } from 'vue-server-renderer'
|
import { createRenderer } from 'vue-server-renderer'
|
||||||
import LRU from 'lru-cache'
|
import LRU from 'lru-cache'
|
||||||
@ -13,29 +12,19 @@ export default class SPARenderer extends BaseRenderer {
|
|||||||
|
|
||||||
this.cache = new LRU()
|
this.cache = new LRU()
|
||||||
|
|
||||||
// Add VueMeta to Vue (this is only for SPA mode)
|
this.vueMetaConfig = {
|
||||||
// See app/index.js
|
|
||||||
Vue.use(VueMeta, {
|
|
||||||
keyName: 'head',
|
keyName: 'head',
|
||||||
attribute: 'data-n-head',
|
attribute: 'data-n-head',
|
||||||
ssrAttribute: 'data-n-head-ssr',
|
ssrAttribute: 'data-n-head-ssr',
|
||||||
|
ssrAppId: '1',
|
||||||
tagIDKeyName: 'hid'
|
tagIDKeyName: 'hid'
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createRenderer () {
|
createRenderer () {
|
||||||
return 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) {
|
async render (renderContext) {
|
||||||
const { url = '/', req = {}, _generate } = renderContext
|
const { url = '/', req = {}, _generate } = renderContext
|
||||||
const modernMode = this.options.modern
|
const modernMode = this.options.modern
|
||||||
@ -54,11 +43,19 @@ export default class SPARenderer extends BaseRenderer {
|
|||||||
HEAD_ATTRS: '',
|
HEAD_ATTRS: '',
|
||||||
BODY_ATTRS: '',
|
BODY_ATTRS: '',
|
||||||
HEAD: '',
|
HEAD: '',
|
||||||
|
BODY_SCRIPTS_PREPEND: '',
|
||||||
BODY_SCRIPTS: ''
|
BODY_SCRIPTS: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get vue-meta context
|
// 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
|
// HTML_ATTRS
|
||||||
meta.HTML_ATTRS = m.htmlAttrs.text()
|
meta.HTML_ATTRS = m.htmlAttrs.text()
|
||||||
@ -78,11 +75,23 @@ export default class SPARenderer extends BaseRenderer {
|
|||||||
m.script.text() +
|
m.script.text() +
|
||||||
m.noscript.text()
|
m.noscript.text()
|
||||||
|
|
||||||
// BODY_SCRIPTS
|
// BODY_SCRIPTS (PREPEND)
|
||||||
meta.BODY_SCRIPTS = m.script.text({ body: true }) + m.noscript.text({ body: true })
|
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
|
// Resources Hints
|
||||||
|
|
||||||
meta.resourceHints = ''
|
meta.resourceHints = ''
|
||||||
|
|
||||||
const { resources: { modernManifest, clientManifest } } = this.serverContext
|
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
|
// Prepare template params
|
||||||
const templateParams = {
|
const templateParams = {
|
||||||
|
@ -109,6 +109,17 @@ export default class SSRRenderer extends BaseRenderer {
|
|||||||
// Inject styles
|
// Inject styles
|
||||||
HEAD += renderContext.renderStyles()
|
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
|
// Serialize state
|
||||||
const serializedSession = `window.${this.serverContext.globals.context}=${devalue(renderContext.nuxt)};`
|
const serializedSession = `window.${this.serverContext.globals.context}=${devalue(renderContext.nuxt)};`
|
||||||
if (shouldInjectScripts) {
|
if (shouldInjectScripts) {
|
||||||
@ -140,12 +151,17 @@ export default class SSRRenderer extends BaseRenderer {
|
|||||||
if (shouldInjectScripts) {
|
if (shouldInjectScripts) {
|
||||||
APP += this.renderScripts(renderContext)
|
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.script.text({ body: true })
|
||||||
APP += m.noscript.text({ body: true })
|
APP += m.noscript.text({ body: true })
|
||||||
|
|
||||||
// Template params
|
// Template params
|
||||||
const templateParams = {
|
const templateParams = {
|
||||||
HTML_ATTRS: 'data-n-head-ssr ' + m.htmlAttrs.text(),
|
HTML_ATTRS: m.htmlAttrs.text(true /* addSrrAttribute */),
|
||||||
HEAD_ATTRS: m.headAttrs.text(),
|
HEAD_ATTRS: m.headAttrs.text(),
|
||||||
BODY_ATTRS: m.bodyAttrs.text(),
|
BODY_ATTRS: m.bodyAttrs.text(),
|
||||||
HEAD,
|
HEAD,
|
||||||
|
Loading…
Reference in New Issue
Block a user