mirror of
https://github.com/nuxt/nuxt.git
synced 2025-02-27 19:15:41 +00:00
parent
4e05650cde
commit
426f32c8c3
@ -129,7 +129,7 @@ useHead({
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
Nuxt uses `unhead` under the hood, and you can refer to its full documentation [here](https://unhead.harlanzw.com/).
|
Nuxt uses `unhead` under the hood, and you can refer to its full documentation [here](https://unhead.unjs.io/).
|
||||||
|
|
||||||
### Modifying The Rendered Head With A Nitro Plugin
|
### Modifying The Rendered Head With A Nitro Plugin
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ Shortcuts are available to make configuration easier: `charset` and `viewport`.
|
|||||||
## `useHead`
|
## `useHead`
|
||||||
|
|
||||||
The [`useHead`](/docs/api/composables/use-head) composable function allows you to manage your head tags in a programmatic and reactive way,
|
The [`useHead`](/docs/api/composables/use-head) composable function allows you to manage your head tags in a programmatic and reactive way,
|
||||||
powered by [Unhead](https://unhead.harlanzw.com/).
|
powered by [Unhead](https://unhead.unjs.io/).
|
||||||
|
|
||||||
As with all composables, it can only be used with a components `setup` and lifecycle hooks.
|
As with all composables, it can only be used with a components `setup` and lifecycle hooks.
|
||||||
|
|
||||||
@ -128,6 +128,29 @@ interface MetaObject {
|
|||||||
|
|
||||||
See [@unhead/schema](https://github.com/unjs/unhead/blob/main/packages/schema/src/schema.ts) for more detailed types.
|
See [@unhead/schema](https://github.com/unjs/unhead/blob/main/packages/schema/src/schema.ts) for more detailed types.
|
||||||
|
|
||||||
|
## Pitfalls
|
||||||
|
|
||||||
|
### Async useHead / useSeoMeta
|
||||||
|
|
||||||
|
A common use case when working with SEO composables is to fetch data from an API and use it to set the page title.
|
||||||
|
However, running `useHead` after an `await` will cause the Nuxt app context to be lost.
|
||||||
|
|
||||||
|
To solve this, you can either:
|
||||||
|
|
||||||
|
- Use `runWithContext` to preserve to context:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const nuxtApp = useNuxtApp();
|
||||||
|
const data = await $fetch(`/api/data/${key}`) // context is lost from the await
|
||||||
|
nuxtApp.runWithContext(() => {
|
||||||
|
useHead({
|
||||||
|
title: `${data.title}`,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
- Enable the experimental flag `asyncContext` in your nuxt.config.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
### Reactivity
|
### Reactivity
|
||||||
|
@ -24,7 +24,7 @@ useHeadSafe({
|
|||||||
// <meta content="0;javascript:alert(1)">
|
// <meta content="0;javascript:alert(1)">
|
||||||
```
|
```
|
||||||
|
|
||||||
Read more on [unhead documentation](https://unhead.harlanzw.com/guide/composables/use-head-safe).
|
Read more on [unhead documentation](https://unhead.unjs.io/usage/composables/use-head-safe).
|
||||||
|
|
||||||
## Type
|
## Type
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ description: useHead customizes the head properties of individual pages of your
|
|||||||
|
|
||||||
# useHead
|
# useHead
|
||||||
|
|
||||||
The [`useHead`](/docs/api/composables/use-head) composable function allows you to manage your head tags in a programmatic and reactive way, powered by [Unhead](https://unhead.harlanzw.com/). If the data comes from a user or other untrusted source, we recommend you check out [`useHeadSafe`](/docs/api/composables/use-head-safe)
|
The [`useHead`](/docs/api/composables/use-head) composable function allows you to manage your head tags in a programmatic and reactive way, powered by [Unhead](https://unhead.unjs.io/). If the data comes from a user or other untrusted source, we recommend you check out [`useHeadSafe`](/docs/api/composables/use-head-safe)
|
||||||
|
|
||||||
:ReadMore{link="/docs/getting-started/seo-meta"}
|
:ReadMore{link="/docs/getting-started/seo-meta"}
|
||||||
|
|
||||||
|
@ -58,9 +58,9 @@
|
|||||||
"@nuxt/telemetry": "^2.4.1",
|
"@nuxt/telemetry": "^2.4.1",
|
||||||
"@nuxt/ui-templates": "^1.3.1",
|
"@nuxt/ui-templates": "^1.3.1",
|
||||||
"@nuxt/vite-builder": "workspace:../vite",
|
"@nuxt/vite-builder": "workspace:../vite",
|
||||||
"@unhead/dom": "^1.3.9",
|
"@unhead/dom": "^1.5.0",
|
||||||
"@unhead/ssr": "^1.3.9",
|
"@unhead/ssr": "^1.5.0",
|
||||||
"@unhead/vue": "^1.3.9",
|
"@unhead/vue": "^1.5.0",
|
||||||
"@vue/shared": "^3.3.4",
|
"@vue/shared": "^3.3.4",
|
||||||
"acorn": "8.10.0",
|
"acorn": "8.10.0",
|
||||||
"c12": "^1.4.2",
|
"c12": "^1.4.2",
|
||||||
|
@ -23,7 +23,7 @@ import { defineRenderHandler, getRouteRules, useRuntimeConfig, useStorage } from
|
|||||||
import { useNitroApp } from '#internal/nitro/app'
|
import { useNitroApp } from '#internal/nitro/app'
|
||||||
|
|
||||||
import type { Link, Script } from '@unhead/vue'
|
import type { Link, Script } from '@unhead/vue'
|
||||||
import { createServerHead } from '@unhead/vue'
|
import { createServerHead, setFailedInjectionHandler as setFailedHeadInjectionHandler } from '@unhead/vue'
|
||||||
// @ts-expect-error virtual file
|
// @ts-expect-error virtual file
|
||||||
import unheadPlugins from '#internal/unhead-plugins.mjs'
|
import unheadPlugins from '#internal/unhead-plugins.mjs'
|
||||||
// eslint-disable-next-line import/no-restricted-paths
|
// eslint-disable-next-line import/no-restricted-paths
|
||||||
@ -247,6 +247,14 @@ export default defineRenderHandler(async (event): Promise<Partial<RenderResponse
|
|||||||
const head = createServerHead({
|
const head = createServerHead({
|
||||||
plugins: unheadPlugins
|
plugins: unheadPlugins
|
||||||
})
|
})
|
||||||
|
if (process.dev) {
|
||||||
|
setFailedHeadInjectionHandler(() => {
|
||||||
|
console.warn('Unhead has fallen back to a shared context. Consider wrapping your code with nuxtApp.runWithContext. Learn more at https://nuxt.com/docs/getting-started/seo-meta#pitfalls.')
|
||||||
|
// dump stacktrace, we don't want to trigger a blocking SSR error
|
||||||
|
// remove the Error on first line
|
||||||
|
console.warn(new Error().stack!.split('\n').slice(5).join('\n'))
|
||||||
|
})
|
||||||
|
}
|
||||||
// needed for hash hydration plugin to work
|
// needed for hash hydration plugin to work
|
||||||
const headEntryOptions: HeadEntryOptions = { mode: 'server' }
|
const headEntryOptions: HeadEntryOptions = { mode: 'server' }
|
||||||
head.push(appHead, headEntryOptions)
|
head.push(appHead, headEntryOptions)
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
"@types/file-loader": "5.0.1",
|
"@types/file-loader": "5.0.1",
|
||||||
"@types/pug": "2.0.6",
|
"@types/pug": "2.0.6",
|
||||||
"@types/sass-loader": "8.0.5",
|
"@types/sass-loader": "8.0.5",
|
||||||
"@unhead/schema": "1.3.9",
|
"@unhead/schema": "1.5.0",
|
||||||
"@vitejs/plugin-vue": "4.3.3",
|
"@vitejs/plugin-vue": "4.3.3",
|
||||||
"@vitejs/plugin-vue-jsx": "3.0.2",
|
"@vitejs/plugin-vue-jsx": "3.0.2",
|
||||||
"@vue/compiler-core": "3.3.4",
|
"@vue/compiler-core": "3.3.4",
|
||||||
|
@ -264,14 +264,14 @@ importers:
|
|||||||
specifier: ^14.18.0 || >=16.10.0
|
specifier: ^14.18.0 || >=16.10.0
|
||||||
version: 18.17.11
|
version: 18.17.11
|
||||||
'@unhead/dom':
|
'@unhead/dom':
|
||||||
specifier: ^1.3.9
|
specifier: ^1.5.0
|
||||||
version: 1.3.9
|
version: 1.5.0
|
||||||
'@unhead/ssr':
|
'@unhead/ssr':
|
||||||
specifier: ^1.3.9
|
specifier: ^1.5.0
|
||||||
version: 1.3.9
|
version: 1.5.0
|
||||||
'@unhead/vue':
|
'@unhead/vue':
|
||||||
specifier: ^1.3.9
|
specifier: ^1.5.0
|
||||||
version: 1.3.9(vue@3.3.4)
|
version: 1.5.0(vue@3.3.4)
|
||||||
'@vue/shared':
|
'@vue/shared':
|
||||||
specifier: ^3.3.4
|
specifier: ^3.3.4
|
||||||
version: 3.3.4
|
version: 3.3.4
|
||||||
@ -479,8 +479,8 @@ importers:
|
|||||||
specifier: 8.0.5
|
specifier: 8.0.5
|
||||||
version: 8.0.5
|
version: 8.0.5
|
||||||
'@unhead/schema':
|
'@unhead/schema':
|
||||||
specifier: 1.3.9
|
specifier: 1.5.0
|
||||||
version: 1.3.9
|
version: 1.5.0
|
||||||
'@vitejs/plugin-vue':
|
'@vitejs/plugin-vue':
|
||||||
specifier: 4.3.3
|
specifier: 4.3.3
|
||||||
version: 4.3.3(vite@4.4.9)(vue@3.3.4)
|
version: 4.3.3(vite@4.4.9)(vue@3.3.4)
|
||||||
@ -2526,6 +2526,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
micromatch: 4.0.5
|
micromatch: 4.0.5
|
||||||
|
napi-wasm: 1.1.0
|
||||||
bundledDependencies:
|
bundledDependencies:
|
||||||
- napi-wasm
|
- napi-wasm
|
||||||
|
|
||||||
@ -3166,41 +3167,41 @@ packages:
|
|||||||
eslint-visitor-keys: 3.4.3
|
eslint-visitor-keys: 3.4.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@unhead/dom@1.3.9:
|
/@unhead/dom@1.5.0:
|
||||||
resolution: {integrity: sha512-bTbPFjXjmk8MC0cBC+7Bgf0Mcw62gsE2XqOhMH/qQo6NP4vR2XGxqy054Y7MGurznR1JVAqxUiU3cR/oxWFk3g==}
|
resolution: {integrity: sha512-zJG35T4jz4i+r5t0+tiFgwY4+F+WLqrdZ2PMRaMXn5noSDMm1q+1X3EhTEgCKq20g+ktXUxv5nhQuDblO6L2pg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@unhead/schema': 1.3.9
|
'@unhead/schema': 1.5.0
|
||||||
'@unhead/shared': 1.3.9
|
'@unhead/shared': 1.5.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@unhead/schema@1.3.9:
|
/@unhead/schema@1.5.0:
|
||||||
resolution: {integrity: sha512-iIa0dczd2qTOxwYZbVR+iAKdlELnLTlKSFsN/YuJ/33sRi5VFa9D8TDBEPLec9gpcjB/bH0FhERfR4bb4UbRuA==}
|
resolution: {integrity: sha512-oalJHsxpcWGXUML62CwpFJaSrbKKbjU3c1eizu7d9/RJS42KKT1LVBXbKrtbR0kNyj4Fbf+MD/DwqZm4cUBcuA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
hookable: 5.5.3
|
hookable: 5.5.3
|
||||||
zhead: 2.0.10
|
zhead: 2.0.10
|
||||||
|
|
||||||
/@unhead/shared@1.3.9:
|
/@unhead/shared@1.5.0:
|
||||||
resolution: {integrity: sha512-lBXK1gzsg3XOnsOgYUVTT2RKOvM+AB0myDXkwQb0jsJB3Tc1qVOSz9JAOR+ZGrosSr7+Iv91+Fu/0E+knxaj2Q==}
|
resolution: {integrity: sha512-34qeSrkKz/KfkD/VR2oWpeOydH5M+8NqNBGwdM9vO/SNeBs+ZCEEO57ASJTSRjjve/rzcBhK6nQG6tOCJtAV1g==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@unhead/schema': 1.3.9
|
'@unhead/schema': 1.5.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@unhead/ssr@1.3.9:
|
/@unhead/ssr@1.5.0:
|
||||||
resolution: {integrity: sha512-FTt4IQOAxHiSfRM7IoJJiFnUEBH8CG5zkJOQ/LydG19QpYa9/AGOi4xvngeCr++1as51p2hWoRO6gPxSRhV8cA==}
|
resolution: {integrity: sha512-lCGUuT5ZDCciyJo4CtM9ZKIB7i2y+FbC+NDi/yUGWnhrwXzKWGBxjktjspWfrwRIX2U1SIFaJk5xoYTMwguUXg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@unhead/schema': 1.3.9
|
'@unhead/schema': 1.5.0
|
||||||
'@unhead/shared': 1.3.9
|
'@unhead/shared': 1.5.0
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@unhead/vue@1.3.9(vue@3.3.4):
|
/@unhead/vue@1.5.0(vue@3.3.4):
|
||||||
resolution: {integrity: sha512-rVAsRLBc+3Y//NRmr7vmRs5yhIf65jYSvcj0V5DtDfDwql7BbGgc3VIIEvY0+EjLQuNsS5kxwm78LSPCIl/3Xw==}
|
resolution: {integrity: sha512-Xz8asfMiD6BAezQXR8XN7JdVdTqcX4T9iv0TL1zSk6SIpdiARLiQKU8inQRxOAxfxksW1+p3BU6siB2CVOcbwQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
vue: '>=2.7 || >=3'
|
vue: '>=2.7 || >=3'
|
||||||
dependencies:
|
dependencies:
|
||||||
'@unhead/schema': 1.3.9
|
'@unhead/schema': 1.5.0
|
||||||
'@unhead/shared': 1.3.9
|
'@unhead/shared': 1.5.0
|
||||||
hookable: 5.5.3
|
hookable: 5.5.3
|
||||||
unhead: 1.3.9
|
unhead: 1.5.0
|
||||||
vue: 3.3.4
|
vue: 3.3.4
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
@ -7063,7 +7064,7 @@ packages:
|
|||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
|
|
||||||
/jstransformer@1.0.0:
|
/jstransformer@1.0.0:
|
||||||
resolution: {integrity: sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==}
|
resolution: {integrity: sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=}
|
||||||
dependencies:
|
dependencies:
|
||||||
is-promise: 2.2.2
|
is-promise: 2.2.2
|
||||||
promise: 7.3.1
|
promise: 7.3.1
|
||||||
@ -7947,6 +7948,9 @@ packages:
|
|||||||
engines: {node: ^14 || ^16 || >=18}
|
engines: {node: ^14 || ^16 || >=18}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
/napi-wasm@1.1.0:
|
||||||
|
resolution: {integrity: sha512-lHwIAJbmLSjF9VDRm9GoVOy9AGp3aIvkjv+Kvz9h16QR3uSVYH78PNQUnT2U4X53mhlnV2M7wrhibQ3GHicDmg==}
|
||||||
|
|
||||||
/natural-compare-lite@1.4.0:
|
/natural-compare-lite@1.4.0:
|
||||||
resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==}
|
resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==}
|
||||||
dev: true
|
dev: true
|
||||||
@ -10206,7 +10210,7 @@ packages:
|
|||||||
engines: {node: '>=0.6'}
|
engines: {node: '>=0.6'}
|
||||||
|
|
||||||
/token-stream@1.0.0:
|
/token-stream@1.0.0:
|
||||||
resolution: {integrity: sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==}
|
resolution: {integrity: sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/totalist@1.1.0:
|
/totalist@1.1.0:
|
||||||
@ -10461,12 +10465,12 @@ packages:
|
|||||||
node-fetch-native: 1.4.0
|
node-fetch-native: 1.4.0
|
||||||
pathe: 1.1.1
|
pathe: 1.1.1
|
||||||
|
|
||||||
/unhead@1.3.9:
|
/unhead@1.5.0:
|
||||||
resolution: {integrity: sha512-vzWZJW8l6dlNM5egJs3c7NMHWZ+iw2x7jCZtU2rrhwFINlKCaA3J42fvOeDxx6t5QR9dfZ96HF2AeNlCcPT+bQ==}
|
resolution: {integrity: sha512-dCbAcYUA5DeYg8+1UrTNhah8OnScuz6Bxc6NmzCl4gWl513aQDzSwRoNEKEhZ/j1vmXVwerUUZdKHTfNcS5NhQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@unhead/dom': 1.3.9
|
'@unhead/dom': 1.5.0
|
||||||
'@unhead/schema': 1.3.9
|
'@unhead/schema': 1.5.0
|
||||||
'@unhead/shared': 1.3.9
|
'@unhead/shared': 1.5.0
|
||||||
hookable: 5.5.3
|
hookable: 5.5.3
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user