docs: improve head section (#19673)

This commit is contained in:
Sébastien Chopin 2023-03-14 15:24:41 +01:00 committed by GitHub
parent a1691721d4
commit e68a23a723
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 54 deletions

View File

@ -7,53 +7,40 @@ description: Improve your Nuxt app's SEO with powerful head config, composables
Improve your Nuxt app's SEO with powerful head config, composables and components. Improve your Nuxt app's SEO with powerful head config, composables and components.
## App Head ## Defaults
Providing an [app.head](/docs/api/configuration/nuxt-config#head) property in your `nuxt.config.ts` allows you to customize the head for your entire app.
::alert{type=info}
This method does not allow you to provide reactive data, if you need global reactive data you can use `useHead` in `app.vue`.
::
Shortcuts are available to make configuration easier: `charset` and `viewport`. You can also provide any of the keys listed below in [Types](#types).
### Defaults
Out-of-the-box, Nuxt provides sane defaults, which you can override if needed. Out-of-the-box, Nuxt provides sane defaults, which you can override if needed.
- `charset`: `utf-8` - `charset`: `utf-8`
- `viewport`: `width=device-width, initial-scale=1` - `viewport`: `width=device-width, initial-scale=1`
### Example ```ts [nuxt.config.ts]
```ts{}[nuxt.config.ts]
export default defineNuxtConfig({ export default defineNuxtConfig({
app: { app: {
head: { head: {
charset: 'utf-16', charset: 'utf-8',
viewport: 'width=500, initial-scale=1', viewport: 'width=device-width, initial-scale=1',
title: 'My App',
meta: [
// <meta name="description" content="My amazing site">
{ name: 'description', content: 'My amazing site.' }
],
} }
} }
}) })
``` ```
:ReadMore{link="/docs/api/configuration/nuxt-config/#head"} Providing an [`app.head`](/docs/api/configuration/nuxt-config#head) property in your [`nuxt.config.ts`](/docs/guide/directory-structure/nuxt.config) allows you to customize the head for your entire app.
## Composable: `useHead` ::alert{type=info}
This method does not allow you to provide reactive data. We recommend to use `useHead()` in `app.vue`.
::
Shortcuts are available to make configuration easier: `charset` and `viewport`. You can also provide any of the keys listed below in [Types](#types).
## `useHead`
The `useHead` composable function allows you to manage your head tags in a programmatic and reactive way, The `useHead` 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.harlanzw.com/).
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.
### Example ```vue [app.vue]
```vue{}[app.vue]
<script setup lang="ts"> <script setup lang="ts">
useHead({ useHead({
title: 'My App', title: 'My App',
@ -68,10 +55,9 @@ useHead({
</script> </script>
``` ```
::ReadMore{link="/docs/api/composables/use-head"} We recommend to take a look at the [`useHead`](/docs/api/composables/use-head) and [`useHeadSafe`](/docs/api/composables/use-head-safe) composables.
::
## Composable: `useSeoMeta` and `useServerSeoMeta` ## `useSeoMeta`
The `useSeoMeta` and `useServerSeoMeta` composables let you define your site's SEO meta tags as a flat object with full TypeScript support. The `useSeoMeta` and `useServerSeoMeta` composables let you define your site's SEO meta tags as a flat object with full TypeScript support.
@ -79,11 +65,9 @@ This helps you avoid typos and common mistakes, such as using `name` instead of
In most instances, the meta does not need to be reactive as robots will only scan the initial load. So we recommend using `useServerSeoMeta` as a performance-focused utility that will not do anything (or return a `head` object) on the client. In most instances, the meta does not need to be reactive as robots will only scan the initial load. So we recommend using `useServerSeoMeta` as a performance-focused utility that will not do anything (or return a `head` object) on the client.
### Example **Simple example:**
#### Simple ```vue [app.vue]
```vue{}[app.vue]
<script setup lang="ts"> <script setup lang="ts">
useServerSeoMeta({ useServerSeoMeta({
title: 'My Amazing Site', title: 'My Amazing Site',
@ -96,14 +80,13 @@ useServerSeoMeta({
</script> </script>
``` ```
#### Reactive **Reactive example:**
When inserting tags that are reactive, for example, from an API request, you should When inserting tags that are reactive, for example, from an API request, you should use the computed getter syntax, the same as `useHead`.
use the computed getter syntax, the same as `useHead`.
```vue{}[app.vue] ```vue [app.vue]
<script setup lang="ts"> <script setup lang="ts">
const data = useFetch(() => $fetch('/api/example')) const { data } = useFetch('/api/example')
useServerSeoMeta({ useServerSeoMeta({
ogTitle: () => `${data.value?.title} - My Site`, ogTitle: () => `${data.value?.title} - My Site`,
@ -113,8 +96,8 @@ useServerSeoMeta({
</script> </script>
``` ```
::ReadMore{link="https://unhead.harlanzw.com/guide/composables/use-seo-meta"} Read more on the [`useSeoMeta`](https://unhead.harlanzw.com/guide/composables/use-seo-meta) composable.
::
## Components ## Components
@ -124,11 +107,9 @@ Because these component names match native HTML elements, it is very important t
`<Head>` and `<Body>` can accept nested meta tags (for aesthetic reasons) but this has no effect on _where_ the nested meta tags are rendered in the final HTML. `<Head>` and `<Body>` can accept nested meta tags (for aesthetic reasons) but this has no effect on _where_ the nested meta tags are rendered in the final HTML.
### Example
<!-- @case-police-ignore html --> <!-- @case-police-ignore html -->
```vue{}[app.vue] ```vue [app.vue]
<script setup> <script setup>
const title = ref('Hello World') const title = ref('Hello World')
</script> </script>
@ -204,7 +185,7 @@ It's recommended to use computed getters (`() => {}`) over computed (`computed((
:: ::
### Title Templates ### Title Template
You can use the `titleTemplate` option to provide a dynamic template for customizing the title of your site. for example, by adding the name of your site to the title of every page. You can use the `titleTemplate` option to provide a dynamic template for customizing the title of your site. for example, by adding the name of your site to the title of every page.
@ -240,7 +221,8 @@ useHead({
script: [ script: [
{ {
src: 'https://third-party-script.com', src: 'https://third-party-script.com',
tagPosition: 'bodyClose' // valid options are: 'head' | 'bodyClose' | 'bodyOpen' // valid options are: 'head' | 'bodyClose' | 'bodyOpen'
tagPosition: 'bodyClose'
} }
] ]
}) })
@ -249,7 +231,7 @@ useHead({
## Examples ## Examples
### Usage With `definePageMeta` ### With `definePageMeta`
Within your `pages/` directory, you can use `definePageMeta` along with `useHead` to set metadata based on the current route. Within your `pages/` directory, you can use `definePageMeta` along with `useHead` to set metadata based on the current route.
@ -280,7 +262,7 @@ useHead({
:ReadMore{link="/docs/guide/directory-structure/pages/#page-metadata"} :ReadMore{link="/docs/guide/directory-structure/pages/#page-metadata"}
### Add Dynamic Title ### Dynamic Title
In the example below, `titleTemplate` is set either as a string with the `%s` placeholder or as a `function`, which allows greater flexibility in setting the page title dynamically for each route of your Nuxt app: In the example below, `titleTemplate` is set either as a string with the `%s` placeholder or as a `function`, which allows greater flexibility in setting the page title dynamically for each route of your Nuxt app:
@ -302,7 +284,7 @@ useHead({
`nuxt.config` is also used as an alternative way of setting the page title. However, `nuxt.config` does not allow the page title to be dynamic. Therefore, it is recommended to use `titleTemplate` in the `app.vue` file to add a dynamic title, which is then applied to all routes of your Nuxt app. `nuxt.config` is also used as an alternative way of setting the page title. However, `nuxt.config` does not allow the page title to be dynamic. Therefore, it is recommended to use `titleTemplate` in the `app.vue` file to add a dynamic title, which is then applied to all routes of your Nuxt app.
### Add External CSS ### External CSS
The example below shows how you might enable Google Fonts using either the `link` property of the `useHead` composable or using the `<Link>` component: The example below shows how you might enable Google Fonts using either the `link` property of the `useHead` composable or using the `<Link>` component:

View File

@ -4,10 +4,26 @@ description: The recommended way to provide head data with user input.
# `useHeadSafe` # `useHeadSafe`
The useHeadSafe composable is a wrapper around the [useHead](/docs/api/composables/use-head) composable that restricts the input to only allow safe values. The `useHeadSafe` composable is a wrapper around the [`useHead`](/docs/api/composables/use-head) composable that restricts the input to only allow safe values.
::ReadMore{link="https://unhead.harlanzw.com/guide/composables/use-head-safe"} ## Usage
::
You can pass all the same values as `useHead`
```ts
useHeadSafe({
script: [
{ id: 'xss-script', innerHTML: 'alert("xss")' }
],
meta: [
{ 'http-equiv': 'refresh', content: '0;javascript:alert(1)' }
]
})
// Will safely generate
// <script id="xss-script"></script>
// <meta content="0;javascript:alert(1)">
```
Read more on [unhead documentation](https://unhead.harlanzw.com/guide/composables/use-head-safe).
## Type ## Type

View File

@ -4,10 +4,9 @@ description: useHead customizes the head properties of individual pages of your
# `useHead` # `useHead`
The `useHead` composable function allows you to manage your head tags in a programmatic and reactive way, powered by [Unhead](https://unhead.harlanzw.com/). The `useHead` 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)
::ReadMore{link="/docs/getting-started/seo-meta"} :ReadMore{link="/docs/getting-started/seo-meta"}
::
## Type ## Type