Skip to content

Commit 8b02eb2

Browse files
authored
feat: add support for global inject options (#568)
* feat: add support for global inject options * feat: use isSSR instead of isSpa
1 parent 92350d5 commit 8b02eb2

File tree

8 files changed

+45
-20
lines changed

8 files changed

+45
-20
lines changed

docs/api/README.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -190,12 +190,16 @@ Updates the current metadata with new metadata.
190190
Useful when updating metadata as the result of an asynchronous action that resolves after the initial render takes place.
191191

192192
### $meta().inject
193+
- arguments
194+
- injectOptions (type: `object`) <Badge text="v2.4+"/>
193195
- returns [`metaInfo`](/api/#metaInfo-properties)
194196

195197
:::tip SSR only
196198
`inject` is available in the server plugin only and is not available on the client
197199
:::
198200

201+
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.
202+
199203
It returns a special `metaInfo` object where all keys have an object as value which contains a `text()` method for returning html code
200204

201205
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
809813
### script.text
810814
### noscript.text
811815
- arguments
812-
- options (type: `object`, default: `{ ln: false , body: false, pbody: false }`)
816+
- options (type: `object`, default: `{ isSSR: true, ln: false , body: false, pbody: false }`)
817+
818+
Set `isSSR: false` if you generate a SPA on server side and want to use the default appId `1` instead of [ssrAppId](/api/#ssrappid)
813819

814820
The `body` and `pbody` props can be used to support positioning of elements in your template, see [SSR Support](#ssr-support)
815821

src/server/generateServerInjector.js

+20-10
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { titleGenerator, attributeGenerator, tagGenerator } from './generators'
99
* @return {Object} - the new injector
1010
*/
1111

12-
export default function generateServerInjector (options, metaInfo) {
12+
export default function generateServerInjector (options, metaInfo, globalInjectOptions) {
1313
const serverInjector = {
1414
data: metaInfo,
1515
extraData: undefined,
@@ -23,15 +23,16 @@ export default function generateServerInjector (options, metaInfo) {
2323
// only call title for the head
2424
return (opts.body || opts.pbody ? '' : m.title.text(opts)) +
2525
m.meta.text(opts) +
26+
m.base.text(opts) +
2627
m.link.text(opts) +
2728
m.style.text(opts) +
2829
m.script.text(opts) +
2930
m.noscript.text(opts)
3031
},
3132
injectors: {
32-
head: ln => serverInjector.callInjectors({ ln }),
33-
bodyPrepend: ln => serverInjector.callInjectors({ ln, pbody: true }),
34-
bodyAppend: ln => serverInjector.callInjectors({ ln, body: true })
33+
head: ln => serverInjector.callInjectors({ ...globalInjectOptions, ln }),
34+
bodyPrepend: ln => serverInjector.callInjectors({ ...globalInjectOptions, ln, pbody: true }),
35+
bodyAppend: ln => serverInjector.callInjectors({ ...globalInjectOptions, ln, body: true })
3536
}
3637
}
3738

@@ -41,19 +42,28 @@ export default function generateServerInjector (options, metaInfo) {
4142
}
4243

4344
serverInjector.injectors[type] = {
44-
text (arg) {
45+
text (injectOptions) {
46+
const addSsrAttribute = injectOptions === true
47+
48+
injectOptions = {
49+
addSsrAttribute,
50+
...globalInjectOptions,
51+
...injectOptions
52+
}
53+
4554
if (type === 'title') {
46-
return titleGenerator(options, type, serverInjector.data[type], arg)
55+
return titleGenerator(options, type, serverInjector.data[type], injectOptions)
4756
}
4857

4958
if (metaInfoAttributeKeys.includes(type)) {
5059
const attributeData = {}
5160

5261
const data = serverInjector.data[type]
5362
if (data) {
63+
const appId = injectOptions.isSSR === false ? '1' : options.ssrAppId
5464
for (const attr in data) {
5565
attributeData[attr] = {
56-
[options.ssrAppId]: data[attr]
66+
[appId]: data[attr]
5767
}
5868
}
5969
}
@@ -72,15 +82,15 @@ export default function generateServerInjector (options, metaInfo) {
7282
}
7383
}
7484

75-
return attributeGenerator(options, type, attributeData, arg)
85+
return attributeGenerator(options, type, attributeData, injectOptions)
7686
}
7787

78-
let str = tagGenerator(options, type, serverInjector.data[type], arg)
88+
let str = tagGenerator(options, type, serverInjector.data[type], injectOptions)
7989

8090
if (serverInjector.extraData) {
8191
for (const appId in serverInjector.extraData) {
8292
const data = serverInjector.extraData[appId][type]
83-
const extraStr = tagGenerator(options, type, data, { appId, ...arg })
93+
const extraStr = tagGenerator(options, type, data, { appId, ...injectOptions })
8494
str = `${str}${extraStr}`
8595
}
8696
}

src/server/generators/attribute.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { booleanHtmlAttributes } from '../../shared/constants'
77
* @param {Object} data - the attributes to generate
88
* @return {Object} - the attribute generator
99
*/
10-
export default function attributeGenerator (options, type, data, addSrrAttribute) {
10+
export default function attributeGenerator (options, type, data, { addSsrAttribute }) {
1111
const { attribute, ssrAttribute } = options || {}
1212
let attributeStr = ''
1313

@@ -32,7 +32,7 @@ export default function attributeGenerator (options, type, data, addSrrAttribute
3232
attributeStr += `${attribute}="${encodeURI(JSON.stringify(data))}"`
3333
}
3434

35-
if (type === 'htmlAttrs' && addSrrAttribute) {
35+
if (type === 'htmlAttrs' && addSsrAttribute) {
3636
return `${ssrAttribute}${attributeStr ? ' ' : ''}${attributeStr}`
3737
}
3838

src/server/generators/tag.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
*/
1717
export default function tagGenerator (options, type, tags, generatorOptions) {
1818
const { ssrAppId, attribute, tagIDKeyName } = options || {}
19-
const { appId, body = false, pbody = false, ln = false } = generatorOptions || {}
19+
const { appId, isSSR = true, body = false, pbody = false, ln = false } = generatorOptions || {}
2020

2121
const dataAttributes = [tagIDKeyName, ...commonDataAttributes]
2222

@@ -40,7 +40,7 @@ export default function tagGenerator (options, type, tags, generatorOptions) {
4040
return tagsStr
4141
}
4242

43-
let attrs = tag.once ? '' : ` ${attribute}="${appId || ssrAppId}"`
43+
let attrs = tag.once ? '' : ` ${attribute}="${appId || (isSSR === false ? '1' : ssrAppId)}"`
4444

4545
// build a string containing all attributes of this tag
4646
for (const attr in tag) {

src/server/inject.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import generateServerInjector from './generateServerInjector'
1313
* @vm {Object} - Vue instance - ideally the root component
1414
* @return {Object} - server meta info with `toString` methods
1515
*/
16-
export default function inject (rootVm, options) {
16+
export default function inject (rootVm, options, injectOptions) {
1717
// make sure vue-meta was initiated
1818
if (!rootVm[rootConfigKey]) {
1919
showWarningNotSupported()
@@ -26,7 +26,7 @@ export default function inject (rootVm, options) {
2626
const metaInfo = getMetaInfo(options, rawInfo, serverSequences, rootVm)
2727

2828
// generate server injector
29-
const serverInjector = generateServerInjector(options, metaInfo)
29+
const serverInjector = generateServerInjector(options, metaInfo, injectOptions)
3030

3131
// add meta info from additional apps
3232
const appsMetaInfo = getAppsMetaInfo()

src/shared/$meta.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export default function $meta (options) {
3838
}
3939
},
4040
refresh: () => refresh($root, options),
41-
inject: () => process.server ? inject($root, options) : showWarningNotSupportedInBrowserBundle('inject'),
41+
inject: injectOptions => process.server ? inject($root, options, injectOptions) : showWarningNotSupportedInBrowserBundle('inject'),
4242
pause: () => pause($root),
4343
resume: () => resume($root),
4444
addApp: appId => addApp($root, appId, options)

test/unit/components.test.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,20 @@ describe('components', () => {
139139
warn.mockRestore()
140140
})
141141

142-
test('meta-info can be rendered with inject', () => {
142+
test('meta-info can be rendered with inject (ssr)', () => {
143143
const wrapper = mount(HelloWorld, { localVue: Vue })
144144

145145
const metaInfo = wrapper.vm.$meta().inject()
146146
expect(metaInfo.title.text()).toEqual('<title>Hello World</title>')
147+
expect(metaInfo.meta.text()).toContain('<meta data-vue-meta="ssr" charset="utf-8">')
148+
})
149+
150+
test('meta-info can be rendered with inject (spa)', () => {
151+
const wrapper = mount(HelloWorld, { localVue: Vue })
152+
153+
const metaInfo = wrapper.vm.$meta().inject({ isSSR: false, ln: true })
154+
expect(metaInfo.title.text()).toEqual('<title>Hello World</title>\n')
155+
expect(metaInfo.meta.text()).toContain('<meta data-vue-meta="1" charset="utf-8">\n')
147156
})
148157

149158
test('inject also renders additional app info', () => {

test/unit/generators.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ describe('extra tests', () => {
135135
expect(meta.bodyPrepend(true)).toBe('<script data-vue-meta="test-app" src="/script.js" data-pbody="true"></script>\n')
136136
expect(meta.bodyAppend()).toBe('<script data-vue-meta="ssr" src="/script.js" data-body="true"></script>')
137137

138-
expect(meta.htmlAttrs.text()).toBe('lang="en" data-vue-meta="%7B%22lang%22:%7B%22ssr%22:%22en%22%7D%7D"')
138+
expect(meta.htmlAttrs.text({ ln: true })).toBe('lang="en" data-vue-meta="%7B%22lang%22:%7B%22ssr%22:%22en%22%7D%7D"')
139139
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"')
140140
})
141141
})

0 commit comments

Comments
 (0)