Блог

Назад
Повний Next.js SEO Чеклист: SSR, динамічні мапи сайту та Core Web Vitals

12 травня 2026 р.

Повний Next.js SEO Чеклист: SSR, динамічні мапи сайту та Core Web Vitals

Next.js змінив правила гри у веб-розробці, запропонувавши гібридний підхід, який поєднує інтерактивність клієнтських додатків із перевагами серверного рендерингу. Для пошукової оптимізації (SEO) ця гібридна модель є надзвичайно потужним інструментом. Звичайні односторінкові додатки (SPA) на базі чистих React-фреймворків часто стикаються з проблемами індексації, оскільки пошукові роботи можуть сканувати сторінку ще до того, як клієнтський JavaScript завершить рендеринг контенту.

Next.js вирішує цю проблему за допомогою попереднього рендерингу на сервері. Проте використання Next.js саме по собі не гарантує автоматичного потрапляння у топ пошукової видачі Google. Висока видимість вимагає правильного проектування архітектури рендерингу, тонкого налаштування метаданих, оптимізації показників Core Web Vitals, побудови автоматизованих динамічних мап сайту та інтеграції структурованих даних. У цьому посібнику ми детально розберемо кожен крок, необхідний для створення технічно бездоганного з точки зору SEO додатку на Next.js.


1. Архітектура рендерингу: вибір між SSR, SSG та ISR

Кожна сторінка вашого додатку може використовувати різну стратегію рендерингу. Вибір цієї стратегії безпосередньо впливає на швидкість відповіді сервера та якість індексації контенту пошуковими роботами.

                           Стратегії рендерингу Next.js
                           
+----------------------------+-----------------------------+----------------------------+
  Static Site Gen (SSG)      | Server-Side Render (SSR)    | Incremental Static (ISR)   
+----------------------------+-----------------------------+----------------------------+
  Генерація під час збірки   | Рендеринг на кожен запит    | Фонове оновлення сторінок  
  Найвища швидкість, ідеально | Для динамічних даних        | Гібридна швидкість і свіжість
+----------------------------+-----------------------------+----------------------------+

Статична генерація (Static Site Generation - SSG)

SSG є найбільш пріоритетним методом для пошукової оптимізації. Під час збірки додатку Next.js компілює сторінки у статичні файли HTML та JSON. Коли користувач або пошуковий робот робить запит, сервер миттєво віддає готовий HTML-файл.

  • Сфера застосування: Статті блогу, сторінки послуг, документація, маркетингові лендінги.
  • Вплив на SEO: Мінімальний час відповіді сервера (Time to First Byte - TTFB), що є критичним фактором ранжування в алгоритмах Google.

Серверний рендеринг (Server-Side Rendering - SSR)

При використанні SSR HTML-документ створюється динамічно на сервері для кожного вхідного запиту.

  • Сфера застосування: Сторінки результатів пошуку, панелі керування користувача, каталоги з фільтрацією в реальному часі.
  • Вплив на SEO: Пошукові роботи отримують повністю сформований HTML з актуальними даними, проте швидкість завантаження сторінки може бути нижчою порівняно з SSG через додатковий час, необхідний для виконання запитів до бази даних та побудови сторінки на сервері.

Інкрементальна статична регенерація (Incremental Static Regeneration - ISR)

ISR дозволяє оновлювати статичні сторінки у фоновому режимі без необхідності повного перезапуску процесу збірки всього сайту. Ви визначаєте інтервал валідації у секундах:

export async function getStaticProps() {
  const data = await fetchUpdatedData();
  return {
    props: { data },
    revalidate: 60, // Перегенерувати сторінку у фоні не частіше ніж раз на 60 секунд
  };
}
  • Вплив на SEO: Ви отримуєте максимальну швидкість завантаження, як у випадку з SSG, і водночас ваш контент залишається свіжим. Робот завжди бачить швидку статичну версію сторінки, поки Next.js оновлює її в асинхронному режимі.

Пастка клієнтського завантаження даних: Уникайте завантаження основного SEO-контенту на стороні клієнта за допомогою useEffect або useSWR. Якщо пошуковий робот просканує сторінку до завершення виконання API-запитів клієнтським скриптом, він проіндексує лише порожній каркас сторінки або індикатор завантаження, що негативно вплине на позиції вашого сайту в пошуку.


2. Динамічне керування метаданими

Метадані (заголовки, описи, теги Open Graph) повідомляють пошуковим системам тему вашої сторінки та визначають її вигляд у результатах пошуку. Дублювання або відсутність метаданих веде до пеналізації з боку Google.

Використання в Pages Router (next/head)

Кожна сторінка повинна містити унікальний блок Head. Слідкуйте за тим, щоб canonical посилання завжди вказували на першоджерело, уникаючи дублювання сторінок через параметри запитів:

import Head from 'next/head';

export default function Article({ post }) {
  return (
    <>
      <Head>
        <title>{`${post.title} | Блог розробника`}</title>
        <meta name="description" content={post.summary} />
        <meta property="og:title" content={post.title} />
        <meta property="og:description" content={post.summary} />
        <meta property="og:image" content={post.featuredImage} />
        <link rel="canonical" href={`https://example.com/blog/${post.slug}`} />
      </Head>
      <article>
        <h1>{post.title}</h1>
        {/* Контент статті */}
      </article>
    </>
  );
}

Використання в App Router (Metadata API)

У сучасних версіях Next.js (13+) інтегровано потужне Metadata API. Замість ручного імпорту компонентів заголовка ви можете експортувати статичний об'єкт metadata або динамічну функцію generateMetadata:

import { Metadata } from 'next';

type Props = {
  params: { slug: string };
};

export async function generateMetadata({ params }: Props): Promise<Metadata> {
  const post = await getPost(params.slug);
  return {
    title: `${post.title} | DevSite`,
    description: post.summary,
    alternates: {
      canonical: `https://example.com/blog/${params.slug}`,
    },
    openGraph: {
      images: [{ url: post.featuredImage }],
    },
  };
}

Next.js автоматично вставить необхідні мета-теги у верхню частину HTML-документу, забезпечуючи коректний рендеринг для парсерів та пошукових роботів.


3. Оптимізація Core Web Vitals: робота з LCP та CLS

Core Web Vitals - це набір метрик, за допомогою яких Google оцінює якість користувацького досвіду на сторінці. Найбільш важливими для пошукового ранжування є:

  • Largest Contentful Paint (LCP): Швидкість завантаження основного вмісту сторінки.
  • Cumulative Layout Shift (CLS): Візуальна стабільність інтерфейсу під час завантаження елементів.

Робота з зображеннями за допомогою next/image

Зображення без чітких розмірів є головною причиною низьких показників CLS, оскільки текст зміщується вниз після повного завантаження картинки. Компонент Image з пакету next/image автоматично генерує адаптивні версії картинок, стискає їх та конвертує у сучасні формати (WebP або AVIF).

Для запобігання зміщенням макету обов'язково вказуйте точні розміри або використовуйте режим заповнення fill:

import Image from 'next/image';

export default function BlogHero({ post }) {
  return (
    <div style={{ position: 'relative', width: '100%', height: '400px' }}>
      <Image
        src={post.image}
        alt={post.title}
        fill
        sizes="(max-width: 768px) 100vw, 800px"
        style={{ objectFit: 'cover' }}
        priority // Завантажує зображення негайно для оптимізації LCP
      />
    </div>
  );
}

Роль атрибуту priority: За замовчуванням Next.js застосовує ліниве завантаження (lazy loading) до всіх зображень. Проте головне зображення статті (hero image) знаходиться у першому екрані та має відображатися відразу. Ліниве завантаження картинок першого екрану штучно збільшує час LCP. Атрибут priority дає браузеру сигнал завантажити цей ресурс у першу чергу.


4. Налаштування багатомовної динамічної мапи сайту

Мапа сайту (sitemap.xml) допомагає пошуковим системам знаходити нові сторінки вашого ресурсу. Якщо ваш додаток підтримує кілька мовних версій, важливо пов'язати їх за допомогою атрибутів hreflang, щоб пошуковик показував відповідну мовну версію користувачам з різних країн.

Нижче наведено приклад реалізації динамічної мапи сайту для Pages Router шляхом створення сторінки pages/sitemap.xml.js:

const SITE_URL = 'https://example.com';
const LOCALES = ['en', 'uk', 'de'];

function generateSiteMap(posts) {
  return `<?xml version="1.0" encoding="UTF-8"?>
   <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
           xmlns:xhtml="http://www.w3.org/1999/xhtml">
     <!-- Головна сторінка -->
     <url>
       <loc>${SITE_URL}</loc>
       <xhtml:link rel="alternate" hreflang="en" href="${SITE_URL}/en" />
       <xhtml:link rel="alternate" hreflang="uk" href="${SITE_URL}/uk" />
       <xhtml:link rel="alternate" hreflang="de" href="${SITE_URL}/de" />
     </url>
     <!-- Динамічні статті блогу -->
     ${posts.map(post => {
       return `
     <url>
       <loc>${SITE_URL}/blog/${post.slug}</loc>
       ${LOCALES.map(loc => `
       <xhtml:link 
         rel="alternate" 
         hreflang="${loc}" 
         href="${SITE_URL}/${loc}/blog/${post.slug}" />`).join('')}
     </url>
     `;
     }).join('')}
   </urlset>
  `;
}

export async function getServerSideProps({ res }) {
  const posts = await getBlogPosts();
  const sitemap = generateSiteMap(posts);

  res.setHeader('Content-Type', 'text/xml');
  res.write(sitemap);
  res.end();

  return { props: {} };
}

export default function Sitemap() {}

Такий підхід захищає ваш сайт від звинувачень у дублюванні контенту та допомагає Google правильно розподіляти позиції між різними мовними версіями статей.


5. Додавання структурованих даних за допомогою JSON-LD

Мікророзмітка дозволяє структурувати інформацію на сторінці для роботів Google. Завдяки правильним структурованим даним ваші посилання у видачі можуть отримати привабливий вигляд (rich snippets), що підвищує клікабельність (CTR).

Для інтеграції розмітки JSON-LD у Next.js використовується стандартний тег скрипта з атрибутом type="application/ld+json":

export default function BlogPost({ post }) {
  const jsonLd = {
    '@context': 'https://schema.org',
    '@type': 'TechArticle',
    'headline': post.title,
    'description': post.summary,
    'image': [post.featuredImage],
    'datePublished': post.date,
    'dateModified': post.lastUpdated || post.date,
    'author': {
      '@type': 'Person',
      'name': 'John Doe',
      'url': 'https://example.com/about'
    },
    'publisher': {
      '@type': 'Organization',
      'name': 'DevSite',
      'logo': {
        '@type': 'ImageObject',
        'url': 'https://example.com/logo.png'
      }
    }
  };

  return (
    <>
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
      />
      <article>
        <h1>{post.title}</h1>
        {/* Рендеринг контенту */}
      </article>
    </>
  );
}

Це дозволяє пошуковій системі миттєво визначити автора, дату публікації, тип матеріалу та пов'язані зображення без необхідності аналізувати весь текстовий масив сторінки.


6. Шрифти та скрипти: робота без блокування основного потоку

Окрім розмірів зображень, на показники швидкості сайту (зокрема Total Blocking Time - TBT та Interaction to Next Paint - INP) сильно впливає завантаження сторонніх шрифтів та аналітичних скриптів.

Шрифти без зміщень за допомогою next/font

Коли ви завантажуєте стандартний шрифт через Google Fonts за допомогою звичайного CSS, браузер спочатку відображає системний шрифт, а після завершення скачування замінює його на кастомний. Це викликає стрибок розміру тексту та різке зміщення всього контенту (що збільшує CLS).

Next.js вирішує цю проблему за допомогою вбудованого модуля next/font. Він завантажує шрифти на етапі збірки проекту, зберігає їх локально та вбудовує спеціальні CSS-налаштування для коригування розмірів системного резервного шрифту. У результаті зміщення тексту при завантаженні стає непомітним:

import { Inter } from 'next/font/google';

const inter = Inter({
  subsets: ['latin', 'cyrillic'],
  display: 'swap', // Показує резервний шрифт до завантаження основного
});

export default function RootLayout({ children }) {
  return (
    <html lang="uk" className={inter.className}>
      <body>{children}</body>
    </html>
  );
}

Неблокуюче підключення аналітики за допомогою next/script

Звичайні сторонні скрипти (Google Analytics, Facebook Pixel, Tag Manager) блокують обробку основного потоку JavaScript, що уповільнює взаємодію користувача зі сторінкою.

Компонент Script з пакету next/script дає змогу гнучко керувати чергою та пріоритетом завантаження зовнішніх ресурсів:

import Script from 'next/script';

export default function Analytics() {
  return (
    <Script
      src="https://www.googletagmanager.com/gtag/js?id=UA-XXXXXX-X"
      strategy="afterInteractive" // Завантажує скрипт після того, як сторінка стане інтерактивною
    />
  );
}

Параметр strategy="afterInteractive" відкладає завантаження скрипта аналітики до моменту повної готовності сторінки до дій користувача, що покращує показники TBT та оптимізує Core Web Vitals для пошукових алгоритмів.

Впровадження всіх пунктів цього чеклисту гарантує вашому додатку на Next.js високі позиції у видачі пошукових систем та ідеальні показники швидкості завантаження.