fix(nuxt): render head scripts that use body: true (#6293)

Co-authored-by: Damian Głowala <48835293+DamianGlowala@users.noreply.github.com>
This commit is contained in:
Harlan Wilton 2022-08-02 21:43:25 +10:00 committed by GitHub
parent 7cc636ad93
commit 622c976cec
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 38 additions and 1 deletions

View File

@ -49,6 +49,28 @@ The `titleTemplate` can either be a string, where `%s` is replaced with the titl
Now, if you set the title to `My Page` with `useHead` on another page of your site, the title would appear as 'My Page - Site Title' in the browser tab. You could also pass `null` to default to the site title. Now, if you set the title to `My Page` with `useHead` on another page of your site, the title would appear as 'My Page - Site Title' in the browser tab. You could also pass `null` to default to the site title.
## Body Meta Tags
::StabilityEdge{title="Body Meta Tags"}
::
You can use the `body: true` option on the `link` and `script` meta tags to append them to the end of the `<body>` tag.
For example:
```vue
<script setup>
useHead({
script: [
{
src: 'https://third-party-script.com',
body: true
}
]
})
</script>
```
## Meta Components ## Meta Components
Nuxt provides `<Title>`, `<Base>`, `<Script>`, `<Style>`, `<Meta>`, `<Link>`, `<Body>`, `<Html>` and `<Head>` components so that you can interact directly with your metadata within your component's template. Nuxt provides `<Title>`, `<Base>`, `<Script>`, `<Style>`, `<Meta>`, `<Link>`, `<Body>`, `<Html>` and `<Head>` components so that you can interact directly with your metadata within your component's template.

View File

@ -171,6 +171,7 @@ export default eventHandler(async (event) => {
bodyAppend: normalizeChunks([ bodyAppend: normalizeChunks([
`<script>window.__NUXT__=${devalue(ssrContext.payload)}</script>`, `<script>window.__NUXT__=${devalue(ssrContext.payload)}</script>`,
_rendered.renderScripts(), _rendered.renderScripts(),
// Note: bodyScripts may contain tags other than <script>
renderedMeta.bodyScripts renderedMeta.bodyScripts
]) ])
} }

View File

@ -55,6 +55,13 @@ export default defineNuxtPlugin((nuxtApp) => {
} }
if (process.server) { if (process.server) {
nuxtApp.ssrContext.renderMeta = () => renderHeadToString(head) nuxtApp.ssrContext.renderMeta = () => {
const meta = renderHeadToString(head)
return {
...meta,
// resolves naming difference with NuxtMeta and @vueuse/head
bodyScripts: meta.bodyTags
}
}
} }
}) })

View File

@ -140,6 +140,7 @@ describe('head tags', () => {
expect(headHtml).toMatch(/<html[^>]*class="html-attrs-test"/) expect(headHtml).toMatch(/<html[^>]*class="html-attrs-test"/)
expect(headHtml).toMatch(/<body[^>]*class="body-attrs-test"/) expect(headHtml).toMatch(/<body[^>]*class="body-attrs-test"/)
expect(headHtml).toContain('script>console.log("works with useMeta too")</script>') expect(headHtml).toContain('script>console.log("works with useMeta too")</script>')
expect(headHtml).toContain('<script src="https://a-body-appended-script.com" data-meta-body="true"></script></body>')
const indexHtml = await $fetch('/') const indexHtml = await $fetch('/')
// should render charset by default // should render charset by default

View File

@ -6,6 +6,12 @@ useHead({
bodyAttrs: { bodyAttrs: {
class: 'body-attrs-test' class: 'body-attrs-test'
}, },
script: [
{
src: 'https://a-body-appended-script.com',
body: true
}
],
meta: [{ name: 'description', content: 'first' }] meta: [{ name: 'description', content: 'first' }]
}) })
useHead({ charset: 'utf-16', meta: [{ name: 'description', content: computed(() => `${a.value} with an inline useHead call`) }] }) useHead({ charset: 'utf-16', meta: [{ name: 'description', content: computed(() => `${a.value} with an inline useHead call`) }] })