SEO и Meta


Улучшите SEO вашего приложения Nuxt с помощью мощной настройки заголовка, составных элементов и компонентов.

Управление тегами 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 по умолчанию, чтобы гарантировать, что ваш веб-сайт будет хорошо работать "из коробки".

  • viewportwidth=device-width, initial-scale=1
  • charsetutf-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>