Технический SEO в Next.js App Router: метаданные, карты сайта и JSON-LD
Узнайте, как вспомогательные инструменты для общих метаданных, стандартная структура корневого элемента, файл robots.ts, динамическая карта сайта, корректно сформированные данные JSON-LD и аудит страниц создают надежную основу для SEO в приложении Next.js.
Источники: How I Got a Next.js Project to 100% SEO on Lighthouse
Приложение Next.js может выглядеть готовым, но по-прежнему оставаться сложным для индексации поисковыми системами: у страниц отсутствуют канонические URL, правила работы роботов не определены, а новый контент никогда не попадает в схему сайта. В этом руководстве рассматривается сайт с API-данными для тестов, у которого на первой проверке SEO-инструмента Lighthouse балл составлял низкий уровень, и показано, как довести его до 100 баллов с помощью семи изменений, внесенных с использованием встроенных API метаданных App Router.
Создание метаданных страниц с помощью одного вспомогательного инструмента
Ручное вводение метаданных на каждой странице приводит к постепенным ошибкам — например, отсутствию канонического URL здесь или устаревшему заголовку Open Graph там. Небольшой фабричный инструмент решает эту проблему: каждая страница передает только свой заголовок, описание, путь и необязательный флаг noIndex, после чего вспомогательный инструмент преобразует их в поля канонического URL, настроек для роботов и информации Open Graph:
export function createPageMetadata({
title,
description,
path,
noIndex = false,
}: PageMetadata) {
return {
title,
description,
alternates: {
canonical: path,
},
robots: noIndex ? "noindex, nofollow" : "index, follow",
openGraph: {
title,
description,
url: path,
type: "website",
},
};
}
Индексация отключается по желанию: один флаг приводит к тому, что страница становится noindex, nofollow. Поскольку path является относительным, вспомогательный инструмент опирается на базовый URL, заданный в корневом макете.
Установите общие настройки для всего сайта в корневом макете
Всё, что используется на всем сайте, должно находиться в экспорте metadata из файла layout.tsx:
metadataBase- шаблон заголовка
- стандартное описание
- настройки Open Graph
- параметры карточки Twitter
- стандартные настройки robots
- атрибут
langв элементе<html>
Упрощённая версия этого экспорта выглядит так:
export const metadata: Metadata = {
metadataBase: new URL("https://mockdata.ir"),
title: {
default: "MockData",
template: "%s | MockData",
},
description: "...",
};
С использованием шаблона %s | MockData страница с названием «Users API» отображается как «Users API | MockData», в то время как страницы без названия используют значение default. Поле metadataBase отвечает за преобразование относительных значений canonical и URL для Open Graph, заданных в хелпере, в абсолютные URL-адреса. Обратите внимание, что lang не является полем метаданных; его следует установить в теге <html>, который отображается в лейауте.
Определение правил парсера с помощью robots.ts
Вместо того чтобы оставить правила парсера неопределенными, генерируйте файл robots.txt из файла app/robots.ts, который возвращает объект типа MetadataRoute.Robots.
export default function robots(): MetadataRoute.Robots {
return {
rules: {
userAgent: "*",
allow: "/",
},
sitemap: "https://mockdata.ir/sitemap.xml",
};
}
Этот файл преднамеренно минимален: все пользовательские агенты могут парсить любой контент, причем указывается местоположение сайт-карты.
Генерация сайт-карты на основе ваших данных
При наличии страниц с ресурсами для пользователей, публикаций, продуктов и многого другого ручно ведомый XML-сайт-карта не способен масштабироваться. По умолчанию экспортируемый файл sitemap.ts может быть async, что позволяет ему запрашивать тот же источник, что и используют страницы:
export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const resources = await getPublicResources();
return [
{
url: "https://mockdata.ir",
lastModified: new Date(),
},
...resources.map((resource) => ({
url: `https://mockdata.ir/${resource.slug}`,
lastModified: resource.updatedAt,
})),
];
}
Каждый ресурс соответствует URL, в котором updatedAt заменяется на lastModified, благодаря чему новые публичные ресурсы автоматически добавляются в сайт-карту. Одно усовершенствование: использование new Date() для главной страницы приводит к отметке об изменениях при каждой генерации; более точным будет использование реального временного метки контента.
Добавляйте структурированные данные только там, где это действительно необходимо
JSON-LD с лексиконом Schema.org информирует поисковые системы о том, что представляет собой страница. Само приложение описывается как SoftwareApplication, а используемые типы — это:
WebSiteOrganizationSoftwareApplication
BreadcrumbListСтарайтесь добиваться точности, а не объема: маркировка должна описывать содержимое, которое действительно находится на странице. Вымышленные отзывы, оценки или другие фиктивные характеристики вводят в заблуждение и могут нарушать руководящие принципы поисковых систем.
Сохраняйте согласованность «хлебных крошек» между интерфейсом и схемой
Вложенные страницы документации показывают видимый путь, например Главная → Документация → API пользователей, и та же иерархия передается в виде структурированных данных BreadcrumbList. Видимый путь и маркировка всегда должны описывать одну и ту же структуру.
Вручную проверяйте каждую индексируемую страницу
Наконец, индивидуально просмотрите каждую публичную страницу:
- Есть ли на ней ровно один четко определенный H1?
- Описывает ли заголовок именно эту конкретную страницу?
- Соответствует ли описание реальному содержимому?
- Есть ли на ней полезные внутренние ссылки туда и обратно?
Не каждый путь должен присутствовать в результатах поиска; часто правильным решением является использование атрибута noindex. Что касается структуры заголовков, ознакомьтесь с этим руководством по семантическому HTML для работы с маркировкой.
Что означает и чего не означает идеальный балл SEO в Lighthouse
После этих исправлений Lighthouse показал балл SEO 100. Это число проверяет такие технические аспекты, как заголовки, описания и возможность индексации; оно ничего не говорит об ранжировании. Ранжирование зависит от качества контента, намерений поисковиков, авторитетности сайта, обратных ссылок, конкуренции, производительности и многих других факторов.
Настоящая ценность заключается в прочной технической основе. Проведение аудита перед публикацией любого приложения Next.js стоит недорого и помогает выявить множество незначительных ошибок.
Основные выводы
- Централизуйте метаданные каждой страницы в специальном помощнике и установите общие параметры по умолчанию, включая
metadataBase, в корневом макете. - Используйте
robots.tsи асинхронный файлsitemap.ts, чтобы правила поисковых роботов и URL оставались синхронизированными с вашими данными. - Добавляйте только структурированные данные, которые точно описывают страницу, и сохраняйте структуру навигационных пунктов одинаковой как в интерфейсе, так и в схеме.
- Рассматривайте параметр
noindexкак законный способ скрыть страницы, которые не должны появляться в результатах поиска. - Оценку Lighthouse 100 следует воспринимать как «технически корректную», а не как гарантию высокого рейтинга.