Meta-теги и SEO

В одностраничных приложениях (SPA), где используется библиотека Navigo, контент обновляется динамически без перезагрузки страницы. Это создаёт проблему: поисковые системы и социальные сети ориентируются на содержимое <head>, включая meta-теги, которые по умолчанию не изменяются при навигации.

Ключевая задача — синхронизировать состояние маршрута Navigo с метаданными страницы:

  • <title>
  • <meta name="description">
  • Open Graph (og:*)
  • Twitter Cards
  • canonical URL

Без этого поисковая оптимизация и корректное отображение ссылок в соцсетях становятся невозможными.


Динамическое управление <title>

Navigo предоставляет обработчики маршрутов, внутри которых можно изменять заголовок страницы.

const router = new Navigo('/');

router.on('/about', () => {
  document.title = 'О компании';
});

router.on('/products', () => {
  document.title = 'Каталог товаров';
});

router.resolve();

Практика:

  • Заголовок должен быть уникальным для каждого маршрута
  • Желательно включать ключевые слова
  • Допускается добавление бренда: Каталог товаров — MyShop

Обновление meta description

Meta-описание напрямую влияет на сниппет в поисковой выдаче.

function setMetaDescription(content) {
  let meta = document.querySelector('meta[name="description"]');

  if (!meta) {
    meta = document.createElement('meta');
    meta.setAttribute('name', 'description');
    document.head.appendChild(meta);
  }

  meta.setAttribute('content', content);
}

Использование в маршрутах:

router.on('/about', () => {
  setMetaDescription('Информация о компании, миссия и команда.');
});

Рекомендации:

  • длина: 120–160 символов
  • избегать дублирования между страницами
  • включать ключевые фразы

Работа с Open Graph

Open Graph используется для предпросмотра ссылок в социальных сетях.

Основные теги:

<meta property="og:title">
<meta property="og:description">
<meta property="og:image">
<meta property="og:url">

Функция для обновления:

function setOGTag(property, content) {
  let element = document.querySelector(`meta[property="${property}"]`);

  if (!element) {
    element = document.createElement('meta');
    element.setAttribute('property', property);
    document.head.appendChild(element);
  }

  element.setAttribute('content', content);
}

Пример:

router.on('/products/:id', ({ data }) => {
  const product = getProductById(data.id);

  setOGTag('og:title', product.name);
  setOGTag('og:description', product.description);
  setOGTag('og:image', product.image);
  setOGTag('og:url', window.location.href);
});

Canonical URL и дубли страниц

В SPA часто возникают проблемы с дублями URL (например, с параметрами или якорями). Canonical помогает указать основную версию страницы.

function setCanonical(url) {
  let link = document.querySelector('link[rel="canonical"]');

  if (!link) {
    link = document.createElement('link');
    link.setAttribute('rel', 'canonical');
    document.head.appendChild(link);
  }

  link.setAttribute('href', url);
}

Использование:

router.on('/products/:id', ({ data }) => {
  setCanonical(`https://example.com/products/${data.id}`);
});

Централизация управления SEO

Для удобства масштабирования применяется единый слой управления метаданными.

function updateMeta({ title, description }) {
  if (title) document.title = title;
  if (description) setMetaDescription(description);
}

Конфигурация маршрутов:

const routes = [
  {
    path: '/',
    meta: {
      title: 'Главная',
      description: 'Главная страница сайта'
    }
  },
  {
    path: '/about',
    meta: {
      title: 'О нас',
      description: 'Информация о компании'
    }
  }
];

routes.forEach(route => {
  router.on(route.path, () => {
    updateMeta(route.meta);
  });
});

Серверный рендеринг и пререндеринг

Navigo работает на клиенте, но поисковые системы лучше индексируют HTML, полученный от сервера.

Подходы:

  1. SSR (Server-Side Rendering)

    • HTML генерируется на сервере
    • meta-теги присутствуют сразу
  2. Пререндеринг

    • генерация статических HTML-страниц
    • подходит для сайтов с фиксированными маршрутами
  3. Динамический рендеринг

    • отдача HTML-версии ботам
    • клиентам — SPA

Обработка 404 страниц

Важно правильно обрабатывать несуществующие маршруты:

router.notFound(() => {
  document.title = 'Страница не найдена';
  setMetaDescription('Запрашиваемая страница не существует');
});

Дополнительно:

  • сервер должен возвращать HTTP 404
  • canonical не должен указывать на существующие страницы

SEO-ограничения SPA

Даже при правильной работе с meta-тегами остаются ограничения:

  • поисковики могут не выполнять JavaScript
  • индексация может происходить с задержкой
  • социальные сети не исполняют JS при генерации превью

Следствие: динамическое обновление meta-тегов в Navigo не заменяет серверную оптимизацию.


Интеграция с аналитикой

Навигация в SPA не вызывает перезагрузку страницы, поэтому необходимо вручную отправлять события.

router.hooks({
  after: (match) => {
    gtag('config', 'GA_MEASUREMENT_ID', {
      page_path: match.url
    });
  }
});

Структура SEO-слоя в SPA

Оптимальная архитектура:

/seo
  meta.js
  og.js
  canonical.js
/router
  routes.js
  index.js

Принципы:

  • изоляция логики SEO
  • переиспользуемые функции
  • декларативное описание маршрутов

Проверка и отладка

Инструменты:

  • DevTools → Elements → <head>
  • Google Rich Results Test
  • Facebook Sharing Debugger
  • Twitter Card Validator

Проверяется:

  • наличие тегов
  • корректность значений
  • соответствие маршруту

Типичные ошибки

1. Meta-теги не обновляются

  • забыта логика в обработчике маршрута

2. Дубли description

  • используется одно значение для всех страниц

3. Отсутствие canonical

  • приводит к проблемам индексации

4. Неправильные OG-данные

  • некорректное отображение ссылок

5. Зависимость только от JS

  • игнорирование SSR или пререндеринга

Расширенные сценарии

Мультиязычные сайты:

setMetaDescription(translations[currentLang].description);

Динамические ключевые слова:

meta.setAttribute('name', 'keywords');
meta.setAttribute('content', product.tags.join(', '));

A/B тестирование SEO:

  • разные description для разных сегментов
  • анализ CTR

Связка Navigo и SEO

Navigo отвечает за:

  • маршрутизацию
  • управление состоянием URL

SEO-слой отвечает за:

  • синхронизацию <head>
  • адаптацию под поисковые системы

Разделение этих обязанностей позволяет:

  • упростить поддержку
  • избежать дублирования кода
  • масштабировать приложение без потери индексации