SEO и Meta
Управление тегами head в Nuxt основано на Unhead. Оно предоставляет оптимальные настройки по умолчанию, несколько мощных компонуемых компонентов и множество вариантов конфигурации для управления заголовками вашего приложения и SEO-метатегами.
Конфигурация Nuxt
Предоставление свойства app.head в вашем nuxt.config.ts позволяет вам статически настраивать head для всего вашего приложения.
useHead() в app.vue.Рекомендуется устанавливать здесь теги, которые не будут меняться, например, название вашего сайта по умолчанию, язык и значок.
// nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
title: 'Nuxt', // заголовок по-умолчанию
htmlAttrs: {
lang: 'en',
},
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
],
},
},
})
Теги по умолчанию
Некоторые теги предоставляются Nuxt по умолчанию, чтобы гарантировать, что ваш веб-сайт будет хорошо работать "из коробки".
viewport:width=device-width, initial-scale=1charset:utf-8
Хотя большинству сайтов не нужно переопределять эти настройки по умолчанию, вы можете обновить их, используя соответствующие свойства.
// nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
// обновить настройки Nuxt по умолчанию
charset: 'utf-16',
viewport: 'width=device-width, initial-scale=1, maximum-scale=1',
},
},
})
useHead
Компонуемая функция useHead поддерживает реактивный ввод, позволяя вам программно управлять тегами head.
<!-- app/app.vue -->
<script setup lang="ts">
useHead({
title: 'My App',
meta: [
{ name: 'description', content: 'Мой удивительный сайт.' },
],
bodyAttrs: {
class: 'test',
},
script: [{ innerHTML: 'console.log(\'Привет, мир\')' }],
})
</script>
Мы рекомендуем ознакомиться с хуками useHead и useHeadSafe.
useSeoMeta
Инструмент useSeoMeta позволяет вам определять SEO мета-теги вашего сайта как объект с полной сохранностью типов.
Это поможет вам избежать опечаток и распространенных ошибок, таких как использование name вместо property.
<!-- app/app.vue -->
<script setup lang="ts">
useSeoMeta({
title: 'Мой удивительный сайт',
ogTitle: 'Мой удивительный сайт',
description: 'Это мой потрясающий сайт, позвольте мне рассказать вам о нем.',
ogDescription: 'Это мой потрясающий сайт, позвольте мне рассказать вам о нем.',
ogImage: 'https://example.com/image.png',
twitterCard: 'summary_large_image',
})
</script>
Компоненты
Хотя использование useHead рекомендуется во всех случаях, у вас могут быть личные предпочтения при определении тегов head в вашем шаблоне с помощью компонентов.
Для этой цели Nuxt предоставляет следующие компоненты: <Title>, <Base>, <NoScript>, <Style>, <Meta>, <Link>, <Body>, <Html> и <Head>. Обратите внимание на заглавные буквы этих компонентов, которые гарантируют, что мы не используем недопустимые собственные HTML-теги.
<Head> и <Body> могут принимать вложенные мета-теги (по эстетическим соображениям), но это не влияет на то, где вложенные мета-теги отображаются в конечном HTML-коде.
<!-- app/app.vue -->
<script setup lang="ts">
const title = ref('Hello World')
</script>
<template>
<div>
<Head>
<Title>{{ title }}</Title>
<Meta
name="description"
:content="title"
/>
<Style>
body { background-color: green; }
</Style>
</Head>
<h1>{{ title }}</h1>
</div>
</template>
Рекомендуется обернуть ваши компоненты либо в <Head>, либо в <Html>, так как теги будут выводиться более интуитивно.
key к компоненту <Head>.Типы
Ниже приведены нереактивные типы, используемые для useHead, app.head и компонентов.
interface MetaObject {
title?: string
titleTemplate?: string | ((title?: string) => string)
templateParams?: Record<string, string | Record<string, string>>
base?: Base
link?: Link[]
meta?: Meta[]
style?: Style[]
script?: Script[]
noscript?: Noscript[]
htmlAttrs?: HtmlAttributes
bodyAttrs?: BodyAttributes
}
Смотрите @unhead/vue для получения более подробной информации о типах.
Особенности
Реактивность
Реактивность поддерживается для всех свойств путем предоставления вычисленного значения, геттера или реактивного объекта.
<!-- useHead -->
<script setup lang="ts">
const description = ref('Мой удивительный сайт.')
useHead({
meta: [
{ name: 'description', content: description },
],
})
</script>
<!-- useSeoMeta -->
<script setup lang="ts">
const description = ref('Мой удивительный сайт.')
useSeoMeta({
description,
})
</script>
<!-- app/Components -->
<script setup lang="ts">
const description = ref('Мой удивительный сайт.')
</script>
<template>
<div>
<Meta
name="description"
:content="description"
/>
</div>
</template>
Шаблон заголовка
Вы можете использовать опцию titleTemplate, чтобы создать динамический шаблон для настройки заголовка вашего сайта. Например, вы можете добавить название своего сайта в заголовок каждой страницы.
titleTemplate может быть либо строкой, где %s заменяется на заголовок, либо функцией.
Если вы хотите использовать функцию (для полного контроля), то это не может быть задано в вашем файле nuxt.config. Вместо этого рекомендуется установить его в вашем файле app.vue, где он будет применяться ко всем страницам вашего сайта:
<script setup lang="ts">
useHead({
titleTemplate: (titleChunk) => {
return titleChunk ? `${titleChunk} - Название сайта` : 'Название сайта'
},
})
</script>
Теперь, если вы установите заголовок "Моя страница" с useHead на другой странице вашего сайта, заголовок будет отображаться как "Моя страница - название сайта" на вкладке браузера. Вы также можете указать значение null по умолчанию для "Названия сайта".
Параметры шаблона
Вы можете использовать templateParams для предоставления дополнительных заполнителей в вашем titleTemplate, помимо значения %s по умолчанию. Это позволяет создавать заголовки более динамично.
<script setup lang="ts">
useHead({
titleTemplate: (titleChunk) => {
return titleChunk ? `${titleChunk} %separator %siteName` : '%siteName'
},
templateParams: {
siteName: 'Название сайта',
separator: '-',
},
})
</script>
Теги body
Вы можете использовать опцию tagPosition: 'bodyClose' для соответствующих тегов, чтобы добавить их в конец тега <body>.
Например:
<script setup lang="ts">
useHead({
script: [
{
src: 'https://third-party-script.com',
// допустимыми вариантами являются: 'head' | 'bodyClose' | 'bodyOpen'
tagPosition: 'bodyClose',
},
],
})
</script>
Примеры
С помощью definePageMeta
В вашем каталоге app/pages/ вы можете использовать definePageMeta вместе с useHead для установки метаданных на основе текущего маршрута.
Например, вы можете сначала задать заголовок текущей страницы (он извлекается во время сборки с помощью макроса, поэтому его нельзя задать динамически).:
<!-- pages/some-page.vue -->
<script setup lang="ts">
definePageMeta({
title: 'Какая-то страница',
})
</script>
А затем в вашем файле макета вы можете использовать метаданные маршрута, которые вы ранее задали:
<!--layouts/default.vue -->
<script setup lang="ts">
const route = useRoute()
useHead({
meta: [{ property: 'og:title', content: `Название приложения - ${route.meta.title}` }],
})
</script>
Динамический заголовок
В приведенном ниже примере titleTemplate задается либо как строка с заполнителем %s, либо как function, что обеспечивает большую гибкость при динамической настройке заголовка страницы для каждого маршрута вашего приложения Nuxt:
<!-- app/app.vue -->
<script setup lang="ts">
useHead({
// как строка,
// где `%s` заменяется на заголовок
titleTemplate: '%s - Название сайта',
})
</script>
<!-- app/app.vue -->
<script setup lang="ts">
useHead({
// или как функция
titleTemplate: (productCategory) => {
return productCategory
? `${productCategory} - Название сайта`
: 'Название сайта'
},
})
</script>
nuxt.config также используется в качестве альтернативного способа настройки заголовка страницы. Однако nuxt.config не позволяет использовать динамический заголовок страницы. Поэтому рекомендуется использовать titleTemplate в файле app.vue, чтобы добавить динамический заголовок, который затем будет применен ко всем маршрутам вашего приложения Nuxt.
Внешний CSS
В приведенном ниже примере показано, как можно включить Google Fonts, используя либо свойство link в компонуемом элементе useHead, либо компонент <Link>.:
<!-- useHead -->
<script setup lang="ts">
useHead({
link: [
{
rel: 'preconnect',
href: 'https://fonts.googleapis.com',
},
{
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Roboto&display=swap',
crossorigin: '',
},
],
})
</script>
<!-- app/Components -->
<template>
<div>
<Link
rel="preconnect"
href="https://fonts.googleapis.com"
/>
<Link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Roboto&display=swap"
crossorigin=""
/>
</div>
</template>