В одностраничных приложениях (SPA), где используется библиотека
Navigo, контент обновляется динамически без перезагрузки страницы. Это
создаёт проблему: поисковые системы и социальные сети ориентируются на
содержимое <head>, включая meta-теги, которые по
умолчанию не изменяются при навигации.
Ключевая задача — синхронизировать состояние маршрута Navigo с метаданными страницы:
<title><meta name="description">og:*)Без этого поисковая оптимизация и корректное отображение ссылок в соцсетях становятся невозможными.
<title>Navigo предоставляет обработчики маршрутов, внутри которых можно изменять заголовок страницы.
const router = new Navigo('/');
router.on('/about', () => {
document.title = 'О компании';
});
router.on('/products', () => {
document.title = 'Каталог товаров';
});
router.resolve();
Практика:
Каталог товаров — MyShopMeta-описание напрямую влияет на сниппет в поисковой выдаче.
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('Информация о компании, миссия и команда.');
});
Рекомендации:
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);
});
В 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}`);
});
Для удобства масштабирования применяется единый слой управления метаданными.
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, полученный от сервера.
Подходы:
SSR (Server-Side Rendering)
Пререндеринг
Динамический рендеринг
Важно правильно обрабатывать несуществующие маршруты:
router.notFound(() => {
document.title = 'Страница не найдена';
setMetaDescription('Запрашиваемая страница не существует');
});
Дополнительно:
Даже при правильной работе с meta-тегами остаются ограничения:
Следствие: динамическое обновление meta-тегов в Navigo не заменяет серверную оптимизацию.
Навигация в SPA не вызывает перезагрузку страницы, поэтому необходимо вручную отправлять события.
router.hooks({
after: (match) => {
gtag('config', 'GA_MEASUREMENT_ID', {
page_path: match.url
});
}
});
Оптимальная архитектура:
/seo
meta.js
og.js
canonical.js
/router
routes.js
index.js
Принципы:
Инструменты:
<head>Проверяется:
1. Meta-теги не обновляются
2. Дубли description
3. Отсутствие canonical
4. Неправильные OG-данные
5. Зависимость только от JS
Мультиязычные сайты:
setMetaDescription(translations[currentLang].description);
Динамические ключевые слова:
meta.setAttribute('name', 'keywords');
meta.setAttribute('content', product.tags.join(', '));
A/B тестирование SEO:
Navigo отвечает за:
SEO-слой отвечает за:
<head>Разделение этих обязанностей позволяет: