Dev Highlights

Доки по разработке

This project is maintained by teniryte

7. SEO, JSON-LD и структурированные данные

Ваш модуль 17-json-ld показывает, как в Next.js:

7.1. Зачем нужен JSON-LD

JSON-LD — это формат структурированных данных, который:

JSON-LD обычно вставляется в <script type="application/ld+json"> внутри <head> или <body>.

7.2. Пример JSON-LD для продукта (Product)

Ваш код строит JSON-LD на основе данных товара:

Паттерн:

// @ts-nocheck

export default async function ProductPage({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = await params;
  const product = await getProduct(id); // любая функция, возвращающая данные товара

  const jsonLd = {
    '@context': 'https://schema.org',
    '@type': 'Product',
    name: product.name,
    image: product.image,
    description: product.description,
  };

  return (
    <section>
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{
          __html: JSON.stringify(jsonLd).replace(/</g, '\\u003c'),
        }}
      />

      {/* здесь основной контент страницы */}
      <h1>{product.name}</h1>
      <p>{product.description}</p>
    </section>
  );
}

Принципы:

7.3. Общий шаблон добавления JSON-LD на страницу

Шаги:

  1. Получаем данные (с БД или внешнего API).
  2. Формируем объект jsonLdData согласно schema.org.
  3. Вставляем его в <script type="application/ld+json"> с dangerouslySetInnerHTML.

Общий пример:

type JsonLd = Record<string, any>;

function JsonLdScript({ data }: { data: JsonLd }) {
  return (
    <script
      type="application/ld+json"
      dangerouslySetInnerHTML={{
        __html: JSON.stringify(data).replace(/</g, '\\u003c'),
      }}
    />
  );
}

export default async function ArticlePage({ params }: { params: { slug: string } }) {
  const article = await getArticleBySlug(params.slug);

  const jsonLd: JsonLd = {
    '@context': 'https://schema.org',
    '@type': 'Article',
    headline: article.title,
    datePublished: article.publishedAt,
    author: {
      '@type': 'Person',
      name: article.authorName,
    },
  };

  return (
    <article>
      <JsonLdScript data={jsonLd} />
      <h1>{article.title}</h1>
      <p>{article.content}</p>
    </article>
  );
}

7.4. Связь JSON-LD с generateMetadata

В ISR‑модуле 14-isr вы уже используете generateMetadata:

Рекомендуемый подход:

Пример синхронизации:

export async function generateMetadata({ params }: { params: { slug: string } }) {
  const article = await getArticleBySlug(params.slug);

  return {
    title: article.title,
    description: article.description,
  };
}

export default async function ArticlePage({ params }: { params: { slug: string } }) {
  const article = await getArticleBySlug(params.slug);

  const jsonLd = {
    '@context': 'https://schema.org',
    '@type': 'Article',
    headline: article.title,
    description: article.description,
    datePublished: article.publishedAt,
  };

  return (
    <article>
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{
          __html: JSON.stringify(jsonLd).replace(/</g, '\\u003c'),
        }}
      />
      <h1>{article.title}</h1>
      <p>{article.content}</p>
    </article>
  );
}

7.5. Типичные схемы JSON-LD

На практике чаще всего используются:

Пример FAQPage:

const jsonLd = {
  '@context': 'https://schema.org',
  '@type': 'FAQPage',
  mainEntity: [
    {
      '@type': 'Question',
      name: 'Как работает ваш сервис?',
      acceptedAnswer: {
        '@type': 'Answer',
        text: 'Мы предоставляем ...',
      },
    },
    {
      '@type': 'Question',
      name: 'Сколько это стоит?',
      acceptedAnswer: {
        '@type': 'Answer',
        text: 'Базовый тариф стоит ...',
      },
    },
  ],
};

Пример BreadcrumbList:

const jsonLd = {
  '@context': 'https://schema.org',
  '@type': 'BreadcrumbList',
  itemListElement: [
    {
      '@type': 'ListItem',
      position: 1,
      name: 'Главная',
      item: 'https://example.com/',
    },
    {
      '@type': 'ListItem',
      position: 2,
      name: 'Блог',
      item: 'https://example.com/blog',
    },
    {
      '@type': 'ListItem',
      position: 3,
      name: 'Конкретная статья',
      item: 'https://example.com/blog/some-article',
    },
  ],
};

7.6. Практические рекомендации по JSON-LD

Ваш модуль 17-json-ld — минимальный, но очень показательный пример, как добавить JSON-LD в Next.js. Этот раздел конспекта поможет быстро восстановить в памяти все шаги: от построения объекта до безопасной вставки в HTML.