логотип PurpleSchool
логотип PurpleSchool

Как настроить HTML-шаблон в Nuxt

Автор

Олег Марков

Введение

Nuxt — это мощный фреймворк для универсальных Vue-приложений, который предлагает множество инструментов для работы с данными и разметкой. В процессе разработки часто возникает задача: добавить или модифицировать HTML-структуру, управлять head-директивами или внедрять пользовательские теги и скрипты. Nuxt предоставляет для этого специальный пакет и удобные механизмы. В этой статье я подробно расскажу, как использовать возможности работы с HTML в Nuxt на примере nuxt-html. Вы увидите, как это реализуется на практике, и узнаете о нюансах, которые важно учитывать для максимальной эффективности вашего приложения.

Основные возможности nuxt-html

Nuxt обрабатывает HTML в нескольких ключевых зонах: это рендеринг содержимого страниц, управление содержимым тега head для SEO и динамики, а также вставка пользовательских фрагментов в нужные части документа. Nuxt-html — это концепция и набор инструментов, которые позволяют разработчикам более гибко интегрировать HTML в Nuxt-приложение.

Давайте рассмотрим детально:

Основы: где и как внедряется HTML в Nuxt

Рендеринг внутри <template>

Основная часть HTML в вашем Nuxt-приложении пишется стандартно во Vue-компонентах внутри блока <template>. Например:

<template>
  <div>
    <h1>Главная страница</h1>
    <p>Это мой первый проект на Nuxt!</p>
  </div>
</template>

Простой компонент отображает заголовок и параграф на странице.

Этот способ отлично подходит для большинства задач, но иногда требуется добавить функционал, который выходит за рамки простых шаблонов. Например, вставить третий-party скрипт или расширить структуру тега head. Здесь подключается nuxt-html.

Настройка HTML-шаблона позволяет контролировать структуру и базовую разметку ваших Nuxt-приложений. Чтобы создавать оптимальные шаблоны, нужно понимать, как Nuxt обрабатывает HTML, как внедрять метаданные и как оптимизировать шаблоны для SEO. Если вы хотите узнать больше о том, как настраивать HTML-шаблон в Nuxt, приходите на наш большой курс Nuxt - fullstack Vue фреймворк. На курсе 129 уроков и 13 упражнений, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.

Управление head при помощи useHead

Nuxt поддерживает декларативное управление метаданными страницы через composable-функцию useHead. Вы можете добавлять любые мета-теги, ссылки, скрипты и другие элементы head.

Смотрите, пример:

<script setup>
// Добавляем страницу title, мета-описание и настраиваем favicon
useHead({
  title: 'Моя страница',
  meta: [
    { name: 'description', content: 'Описание моей страницы' }
  ],
  link: [
    { rel: 'icon', type: 'image/png', href: '/favicon.png' }
  ]
})
</script>

Этот код добавляет title, мета-описание и иконку страницы.

Особенности SSR и гибридной генерации

Nuxt генерирует HTML как на стороне сервера (SSR), так и во время сборки статических сайтов (SSG). У вас есть возможность добавлять или менять HTML на разных этапах: до рендеринга страницы, в момент рендера, после взаимодействия на клиенте. Это позволяет, например, внедрять условия в head и body по разным сценариям.

Вставка HTML-фрагментов с v-html

Иногда необходимо отрендерить не заранее известный HTML-шаблон, а динамический HTML, приходящий, например, из API. Для этого используется директива v-html.

Вот как это выглядит:

<template>
  <div v-html="rawHtml"></div>
</template>

<script setup>
const rawHtml = '<span style="color: red">Важное сообщение</span>'
</script>

В div будет отрендерен HTML-код, управляемый переменной rawHtml.

Внимание: Использование v-html потенциально опасно (риск XSS-атак). Обязательно фильтруйте и санитизируйте HTML, полученный извне.

Nuxt-html: работа с head, body и custom HTML

Декларативное управление head в pages, layout, components

Вы можете управлять содержимым тега head как глобально (в layouts/default.vue), так и на уровне отдельной страницы или компонента.

<script setup>
// Используем useHead для добавления open graph тегов для соцсетей
useHead({
  meta: [
    { property: 'og:title', content: 'Nuxt обучение' },
    { property: 'og:type', content: 'website' }
  ],
  script: [
    { src: 'https://cdn.example.com/track.js', async: true }
  ]
})
</script>

Здесь добавляются OG-мета и сторонний скрипт.

Расширение HTML-документа через app.vue

В файле app.vue можно задать основной формат HTML-разметки главного документа (не страницы). Особенно полезно, если нужно вставить кастомные теги в head или body, например для глобальных стилей, сервисов аналитики, CDN-линков.

<template>
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
</template>

<script setup>
useHead({
  link: [
    { rel: 'stylesheet', href: 'https://cdn.example.com/main.css' }
  ],
  script: [
    { innerHTML: 'window.GLOBAL_VAR = true;', type: 'text/javascript' }
  ],
  __dangerouslyDisableSanitizersByTagID: {
    'customScript': ['innerHTML']
  }
})
</script>

Здесь на уровень приложения подключен внешний стиль и добавлен инлайн-скрипт.

Использование nuxt-h3 и slots для работы с body

Если вам требуется более глубоко взаимодействовать с HTML-body (например, добавить элемент вне области Vue-компонентов), используйте слоты и middleware или нативное взаимодействие через серверный модуль nuxt-h3.

Пример включения кастомного div в body:

<template>
  <div>
    <slot />
    <div id="custom-footer">Авторское уведомление</div>
  </div>
</template>

Компонент автоматически добавляет в конец body кастомный блок.

Специфика внешних HTML-ресурсов и интеграция SEO

Динамическая генерация метатегов

Для SEO критически важно, чтобы каждая страница имела уникальные title и description. В Nuxt это обычно делается через useHead:

<script setup>
const { data } = await useFetch('/api/article?id=5')

useHead({
  title: data.value.title,
  meta: [
    { name: 'description', content: data.value.summary }
  ]
})
</script>

Тайтл и описание строятся динамически из API.

Вставка Google Analytics, счетчиков или других внешних сервисов

Nuxt-head поддерживает добавление всевозможных скриптов для аналитики, пикселей и прочих сервисов. Достаточно добавить соответствующий блок в script или noscript, например:

<script setup>
useHead({
  script: [
    {
      // Подключаем Google Analytics
      src: 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXX',
      async: true
    }
  ],
  noscript: [
    {
      innerHTML: '<div><img src="https://mc.yandex.ru/watch/XXXXXX" style="position:absolute; left:-9999px;" alt="" /></div>'
    }
  ]
})
</script>

Включаем скрипты и теги для метрик.

Работа с динамическим HTML: API, JSON и безопасность

Иногда приходится работать с HTML, который приходит от внешних сервисов. Например, у вас есть блог или статьи, где содержимое хранится как HTML-текст в базе данных.

Пример получения и вывода HTML из API

<template>
  <div v-html="articleHtml"></div>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const articleHtml = ref('')

onMounted(async () => {
  const res = await fetch('/api/article?id=10')
  const json = await res.json()
  articleHtml.value = json.htmlBody // Получили HTML с сервера
})
</script>

HTML контент будет показан на странице.

Важно: Следите за безопасностью! Если управляете внешним HTML, применяйте sanitizer, например DOMPurify, особенно если проект открыт для пользовательских публикаций.

Интеграция с markdown и HTML

Часто контент доступен в markdown-формате, который может конвертироваться в HTML (например, через remark или markdown-it).

import markdownIt from 'markdown-it'

const md = markdownIt()
const html = md.render('# Мой заголовок\n\n - Список\n - Элементов')

Этот код конвертирует Markdown в HTML, который потом можно использовать с v-html.

Плагин nuxt-content и nuxt-html

Плагин @nuxt/content позволяет удобно хранить контент в формате Markdown или JSON и использовать его как HTML. Контент автоматически преобразуется и может выводиться на страницу с помощью компонента <nuxt-content /> или через v-html.

Пример работы c nuxt-content

<template>
  <article>
    <nuxt-content :document="article"/>
  </article>
</template>

<script setup>
const { data: article } = await useAsyncData('article', () =>
  fetchContent('/articles/my-page').then(res => res.body)
)
</script>

Так хранится и рендерится статья, написанная в Markdown.

Заключение

Nuxt предоставляет продуманные и гибкие инструменты для внедрения и управления HTML в ваших приложениях. Управление head, работа с динамическим содержимым, обработка сторонних скриптов, генерация SEO-метаданных и вывод HTML с внешних сервисов — все это делается просто и удобно через встроенные синтаксисы и API. Используйте useHead и директиву v-html там, где это оправдано, и не забывайте о безопасности, если внедряете HTML снаружи. Nuxt-html концепция и инструментарий отлично справляются с задачами любого уровня сложности, а также позволяют создавать современные, динамичные и удобные для пользователя приложения.

Работа с HTML-шаблонами - это важный аспект веб-разработки. Чтобы создавать гибкие и масштабируемые приложения, необходимо освоить все возможности фреймворка, включая работу с сервером, базами данных и API. На нашем курсе Nuxt - fullstack Vue фреймворк вы найдете все необходимые знания и навыки для достижения успеха. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в Nuxt прямо сегодня.

Частозадаваемые технические вопросы по теме статьи

Как добавить теги meta/og только на определенной странице в Nuxt?

Добавьте useHead или definePageMeta непосредственно в файле страницы внутри блока <script setup>. Указанные теги будут применены только к этой странице, все остальные страницы их не наследуют.

Можно ли изменить содержимое тега body или добавить кастомные скрипты вне head?

Да, но только через app.vue, layout или плагины. Для инъекций вне используйте runtime-хуки, плагины или сторонние Nuxt-модули, влияющие на SSR-рендер.

Как обезопасить себя от XSS, если приходится использовать v-html?

Применяйте популярные пакеты sanitizer, например DOMPurify. Установите библиотеку, обрабатывайте любые внешние HTML-данные через sanitizer перед выводом на страницу с v-html.

Как вывести HTML-текст, полученный из Markdown, внутри компонента Nuxt?

Конвертируйте Markdown в HTML с помощью markdown-it (или используйте @nuxt/content), затем выводите через v-html или компонент nuxt-content. Не забывайте санитизировать HTML, если Markdown может содержать пользовательский ввод.

Как добавить кастомные теги в head для сервисов, которые требуют специфических атрибутов?

В useHead можно добавлять любые свойства. Например: useHead({ meta: [{ 'http-equiv': 'Content-Security-Policy', content: 'upgrade-insecure-requests' }] }) В object, описывающем тег, пишите любые нужные атрибуты. Если требуется вставить raw-HTML, используйте innerHTML и __dangerouslyDisableSanitizersByTagID.

Стрелочка влевоРабота с JSON-данными в NuxtГенерация статического сайта с помощью NuxtСтрелочка вправо

Постройте личный план изучения Nuxt до уровня Middle — бесплатно!

Nuxt — часть карты развития Frontend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по Nuxt

Генерация статического сайта с помощью NuxtКак использовать useAsyncData в NuxtКак использовать SVG в NuxtКоманды для запуска NuxtРабота с JSON-данными в NuxtКак настроить HTML-шаблон в NuxtГенерация статического сайта с помощью NuxtРуководство по получению данных с Fetch в NuxtКак отключить определенные функции в NuxtРабота с данными в Nuxt с помощью useNuxtDataНастройка и использование cookie в NuxtГайд по аутентификации (auth) в NuxtКак создавать API-маршруты в Nuxt
Использование Vite для ускорения разработки в NuxtРуководство по использованию TypeScript в NuxtКак запустить Nuxt-приложение в productionКак работает Server-Side Rendering SSR в NuxtНастройка и оптимизация серверной части Nuxt-приложенияРуководство по настройке маршрутизации в NuxtКакие проекты разумно реализовывать на NuxtИнструкция по управлению пакетами NPM в NuxtИнтеграция Node.js для Nuxt-приложенияНастройка мета-тегов для SEO в NuxtНастройка и использование HTTPS в NuxtКак отлавливать и обрабатывать ошибки в NuxtКак развернуть Nuxt приложение в DockerРуководство по развертыванию приложений в Nuxt CloudКак оптимизировать сборку на NuxtИнтеграция Laravel и Nuxt
Открыть базу знаний

Лучшие курсы по теме

Иконка ракетыСкоро!
изображение курса

Nuxt

Антон Ларичев
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажеры
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
Практика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий