mirror of
https://github.com/tenrok/vue-meta.git
synced 2026-06-24 00:30:33 +03:00
feat: add support for global inject options (#568)
* feat: add support for global inject options * feat: use isSSR instead of isSpa
This commit is contained in:
+7
-1
@@ -190,12 +190,16 @@ Updates the current metadata with new metadata.
|
|||||||
Useful when updating metadata as the result of an asynchronous action that resolves after the initial render takes place.
|
Useful when updating metadata as the result of an asynchronous action that resolves after the initial render takes place.
|
||||||
|
|
||||||
### $meta().inject
|
### $meta().inject
|
||||||
|
- arguments
|
||||||
|
- injectOptions (type: `object`) <Badge text="v2.4+"/>
|
||||||
- returns [`metaInfo`](/api/#metaInfo-properties)
|
- returns [`metaInfo`](/api/#metaInfo-properties)
|
||||||
|
|
||||||
:::tip SSR only
|
:::tip SSR only
|
||||||
`inject` is available in the server plugin only and is not available on the client
|
`inject` is available in the server plugin only and is not available on the client
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
You can pass an object to inject with global inject options. See [SSR injection method arguments](/api/#noscript-text) for a list of available options.
|
||||||
|
|
||||||
It returns a special `metaInfo` object where all keys have an object as value which contains a `text()` method for returning html code
|
It returns a special `metaInfo` object where all keys have an object as value which contains a `text()` method for returning html code
|
||||||
|
|
||||||
See [Rendering with renderToString](/guide/ssr.html#simple-rendering-with-rendertostring) for an example
|
See [Rendering with renderToString](/guide/ssr.html#simple-rendering-with-rendertostring) for an example
|
||||||
@@ -809,7 +813,9 @@ See the [SSR guide](/guide/ssr.html#inject-metadata-into-page-string) for more i
|
|||||||
### script.text
|
### script.text
|
||||||
### noscript.text
|
### noscript.text
|
||||||
- arguments
|
- arguments
|
||||||
- options (type: `object`, default: `{ ln: false , body: false, pbody: false }`)
|
- options (type: `object`, default: `{ isSSR: true, ln: false , body: false, pbody: false }`)
|
||||||
|
|
||||||
|
Set `isSSR: false` if you generate a SPA on server side and want to use the default appId `1` instead of [ssrAppId](/api/#ssrappid)
|
||||||
|
|
||||||
The `body` and `pbody` props can be used to support positioning of elements in your template, see [SSR Support](#ssr-support)
|
The `body` and `pbody` props can be used to support positioning of elements in your template, see [SSR Support](#ssr-support)
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { titleGenerator, attributeGenerator, tagGenerator } from './generators'
|
|||||||
* @return {Object} - the new injector
|
* @return {Object} - the new injector
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export default function generateServerInjector (options, metaInfo) {
|
export default function generateServerInjector (options, metaInfo, globalInjectOptions) {
|
||||||
const serverInjector = {
|
const serverInjector = {
|
||||||
data: metaInfo,
|
data: metaInfo,
|
||||||
extraData: undefined,
|
extraData: undefined,
|
||||||
@@ -23,15 +23,16 @@ export default function generateServerInjector (options, metaInfo) {
|
|||||||
// only call title for the head
|
// only call title for the head
|
||||||
return (opts.body || opts.pbody ? '' : m.title.text(opts)) +
|
return (opts.body || opts.pbody ? '' : m.title.text(opts)) +
|
||||||
m.meta.text(opts) +
|
m.meta.text(opts) +
|
||||||
|
m.base.text(opts) +
|
||||||
m.link.text(opts) +
|
m.link.text(opts) +
|
||||||
m.style.text(opts) +
|
m.style.text(opts) +
|
||||||
m.script.text(opts) +
|
m.script.text(opts) +
|
||||||
m.noscript.text(opts)
|
m.noscript.text(opts)
|
||||||
},
|
},
|
||||||
injectors: {
|
injectors: {
|
||||||
head: ln => serverInjector.callInjectors({ ln }),
|
head: ln => serverInjector.callInjectors({ ...globalInjectOptions, ln }),
|
||||||
bodyPrepend: ln => serverInjector.callInjectors({ ln, pbody: true }),
|
bodyPrepend: ln => serverInjector.callInjectors({ ...globalInjectOptions, ln, pbody: true }),
|
||||||
bodyAppend: ln => serverInjector.callInjectors({ ln, body: true })
|
bodyAppend: ln => serverInjector.callInjectors({ ...globalInjectOptions, ln, body: true })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,9 +42,17 @@ export default function generateServerInjector (options, metaInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
serverInjector.injectors[type] = {
|
serverInjector.injectors[type] = {
|
||||||
text (arg) {
|
text (injectOptions) {
|
||||||
|
const addSsrAttribute = injectOptions === true
|
||||||
|
|
||||||
|
injectOptions = {
|
||||||
|
addSsrAttribute,
|
||||||
|
...globalInjectOptions,
|
||||||
|
...injectOptions
|
||||||
|
}
|
||||||
|
|
||||||
if (type === 'title') {
|
if (type === 'title') {
|
||||||
return titleGenerator(options, type, serverInjector.data[type], arg)
|
return titleGenerator(options, type, serverInjector.data[type], injectOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (metaInfoAttributeKeys.includes(type)) {
|
if (metaInfoAttributeKeys.includes(type)) {
|
||||||
@@ -51,9 +60,10 @@ export default function generateServerInjector (options, metaInfo) {
|
|||||||
|
|
||||||
const data = serverInjector.data[type]
|
const data = serverInjector.data[type]
|
||||||
if (data) {
|
if (data) {
|
||||||
|
const appId = injectOptions.isSSR === false ? '1' : options.ssrAppId
|
||||||
for (const attr in data) {
|
for (const attr in data) {
|
||||||
attributeData[attr] = {
|
attributeData[attr] = {
|
||||||
[options.ssrAppId]: data[attr]
|
[appId]: data[attr]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,15 +82,15 @@ export default function generateServerInjector (options, metaInfo) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return attributeGenerator(options, type, attributeData, arg)
|
return attributeGenerator(options, type, attributeData, injectOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
let str = tagGenerator(options, type, serverInjector.data[type], arg)
|
let str = tagGenerator(options, type, serverInjector.data[type], injectOptions)
|
||||||
|
|
||||||
if (serverInjector.extraData) {
|
if (serverInjector.extraData) {
|
||||||
for (const appId in serverInjector.extraData) {
|
for (const appId in serverInjector.extraData) {
|
||||||
const data = serverInjector.extraData[appId][type]
|
const data = serverInjector.extraData[appId][type]
|
||||||
const extraStr = tagGenerator(options, type, data, { appId, ...arg })
|
const extraStr = tagGenerator(options, type, data, { appId, ...injectOptions })
|
||||||
str = `${str}${extraStr}`
|
str = `${str}${extraStr}`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { booleanHtmlAttributes } from '../../shared/constants'
|
|||||||
* @param {Object} data - the attributes to generate
|
* @param {Object} data - the attributes to generate
|
||||||
* @return {Object} - the attribute generator
|
* @return {Object} - the attribute generator
|
||||||
*/
|
*/
|
||||||
export default function attributeGenerator (options, type, data, addSrrAttribute) {
|
export default function attributeGenerator (options, type, data, { addSsrAttribute }) {
|
||||||
const { attribute, ssrAttribute } = options || {}
|
const { attribute, ssrAttribute } = options || {}
|
||||||
let attributeStr = ''
|
let attributeStr = ''
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ export default function attributeGenerator (options, type, data, addSrrAttribute
|
|||||||
attributeStr += `${attribute}="${encodeURI(JSON.stringify(data))}"`
|
attributeStr += `${attribute}="${encodeURI(JSON.stringify(data))}"`
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === 'htmlAttrs' && addSrrAttribute) {
|
if (type === 'htmlAttrs' && addSsrAttribute) {
|
||||||
return `${ssrAttribute}${attributeStr ? ' ' : ''}${attributeStr}`
|
return `${ssrAttribute}${attributeStr ? ' ' : ''}${attributeStr}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
*/
|
*/
|
||||||
export default function tagGenerator (options, type, tags, generatorOptions) {
|
export default function tagGenerator (options, type, tags, generatorOptions) {
|
||||||
const { ssrAppId, attribute, tagIDKeyName } = options || {}
|
const { ssrAppId, attribute, tagIDKeyName } = options || {}
|
||||||
const { appId, body = false, pbody = false, ln = false } = generatorOptions || {}
|
const { appId, isSSR = true, body = false, pbody = false, ln = false } = generatorOptions || {}
|
||||||
|
|
||||||
const dataAttributes = [tagIDKeyName, ...commonDataAttributes]
|
const dataAttributes = [tagIDKeyName, ...commonDataAttributes]
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ export default function tagGenerator (options, type, tags, generatorOptions) {
|
|||||||
return tagsStr
|
return tagsStr
|
||||||
}
|
}
|
||||||
|
|
||||||
let attrs = tag.once ? '' : ` ${attribute}="${appId || ssrAppId}"`
|
let attrs = tag.once ? '' : ` ${attribute}="${appId || (isSSR === false ? '1' : ssrAppId)}"`
|
||||||
|
|
||||||
// build a string containing all attributes of this tag
|
// build a string containing all attributes of this tag
|
||||||
for (const attr in tag) {
|
for (const attr in tag) {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import generateServerInjector from './generateServerInjector'
|
|||||||
* @vm {Object} - Vue instance - ideally the root component
|
* @vm {Object} - Vue instance - ideally the root component
|
||||||
* @return {Object} - server meta info with `toString` methods
|
* @return {Object} - server meta info with `toString` methods
|
||||||
*/
|
*/
|
||||||
export default function inject (rootVm, options) {
|
export default function inject (rootVm, options, injectOptions) {
|
||||||
// make sure vue-meta was initiated
|
// make sure vue-meta was initiated
|
||||||
if (!rootVm[rootConfigKey]) {
|
if (!rootVm[rootConfigKey]) {
|
||||||
showWarningNotSupported()
|
showWarningNotSupported()
|
||||||
@@ -26,7 +26,7 @@ export default function inject (rootVm, options) {
|
|||||||
const metaInfo = getMetaInfo(options, rawInfo, serverSequences, rootVm)
|
const metaInfo = getMetaInfo(options, rawInfo, serverSequences, rootVm)
|
||||||
|
|
||||||
// generate server injector
|
// generate server injector
|
||||||
const serverInjector = generateServerInjector(options, metaInfo)
|
const serverInjector = generateServerInjector(options, metaInfo, injectOptions)
|
||||||
|
|
||||||
// add meta info from additional apps
|
// add meta info from additional apps
|
||||||
const appsMetaInfo = getAppsMetaInfo()
|
const appsMetaInfo = getAppsMetaInfo()
|
||||||
|
|||||||
+1
-1
@@ -38,7 +38,7 @@ export default function $meta (options) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
refresh: () => refresh($root, options),
|
refresh: () => refresh($root, options),
|
||||||
inject: () => process.server ? inject($root, options) : showWarningNotSupportedInBrowserBundle('inject'),
|
inject: injectOptions => process.server ? inject($root, options, injectOptions) : showWarningNotSupportedInBrowserBundle('inject'),
|
||||||
pause: () => pause($root),
|
pause: () => pause($root),
|
||||||
resume: () => resume($root),
|
resume: () => resume($root),
|
||||||
addApp: appId => addApp($root, appId, options)
|
addApp: appId => addApp($root, appId, options)
|
||||||
|
|||||||
@@ -139,11 +139,20 @@ describe('components', () => {
|
|||||||
warn.mockRestore()
|
warn.mockRestore()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('meta-info can be rendered with inject', () => {
|
test('meta-info can be rendered with inject (ssr)', () => {
|
||||||
const wrapper = mount(HelloWorld, { localVue: Vue })
|
const wrapper = mount(HelloWorld, { localVue: Vue })
|
||||||
|
|
||||||
const metaInfo = wrapper.vm.$meta().inject()
|
const metaInfo = wrapper.vm.$meta().inject()
|
||||||
expect(metaInfo.title.text()).toEqual('<title>Hello World</title>')
|
expect(metaInfo.title.text()).toEqual('<title>Hello World</title>')
|
||||||
|
expect(metaInfo.meta.text()).toContain('<meta data-vue-meta="ssr" charset="utf-8">')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('meta-info can be rendered with inject (spa)', () => {
|
||||||
|
const wrapper = mount(HelloWorld, { localVue: Vue })
|
||||||
|
|
||||||
|
const metaInfo = wrapper.vm.$meta().inject({ isSSR: false, ln: true })
|
||||||
|
expect(metaInfo.title.text()).toEqual('<title>Hello World</title>\n')
|
||||||
|
expect(metaInfo.meta.text()).toContain('<meta data-vue-meta="1" charset="utf-8">\n')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('inject also renders additional app info', () => {
|
test('inject also renders additional app info', () => {
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ describe('extra tests', () => {
|
|||||||
expect(meta.bodyPrepend(true)).toBe('<script data-vue-meta="test-app" src="/script.js" data-pbody="true"></script>\n')
|
expect(meta.bodyPrepend(true)).toBe('<script data-vue-meta="test-app" src="/script.js" data-pbody="true"></script>\n')
|
||||||
expect(meta.bodyAppend()).toBe('<script data-vue-meta="ssr" src="/script.js" data-body="true"></script>')
|
expect(meta.bodyAppend()).toBe('<script data-vue-meta="ssr" src="/script.js" data-body="true"></script>')
|
||||||
|
|
||||||
expect(meta.htmlAttrs.text()).toBe('lang="en" data-vue-meta="%7B%22lang%22:%7B%22ssr%22:%22en%22%7D%7D"')
|
expect(meta.htmlAttrs.text({ ln: true })).toBe('lang="en" data-vue-meta="%7B%22lang%22:%7B%22ssr%22:%22en%22%7D%7D"')
|
||||||
expect(meta.bodyAttrs.text()).toBe('class="base-class extra-class" data-vue-meta="%7B%22class%22:%7B%22ssr%22:%22base-class%22,%22test-app%22:%22extra-class%22%7D%7D"')
|
expect(meta.bodyAttrs.text()).toBe('class="base-class extra-class" data-vue-meta="%7B%22class%22:%7B%22ssr%22:%22base-class%22,%22test-app%22:%22extra-class%22%7D%7D"')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user