Добавляем пагинацию в статический блог на Next.js

Инструкция по добавлению пагинации постов в статическом блоге на Next.js.

Добавляем пагинацию в статический блог на Next.js
Дата публикации
03.06.24
Время чтения
4 мин.
Автор
Алексей Баранов

Продолжаем работать над улучшением блога и одновременно разбираться в Next.js. В этой статье расскажем как добавить пагинацию к статическим страницам блога.

Процесс можно разделить на несколько этапов:

Результат можно посмотреть в самом низу страницы с постами.

Разделение логики страницы на динамическую и статическую

Нам не хотелось менять структуру страниц сайта, поэтому мы решили что страницу будем прокидывать через query string.

Статические страницы в Next.js имеют ряд ограничений при работе с query string. По сути, единственный доступный в моём случае способ получить доступ к параметрам из URL - воспользоваться хуком useSearchParams из клиентского компонента.

Для этого необходимо вынести получение данных о постах в код статической страницы, и передать их в клиентский компонент, который сможет отфильтровать их нужным нам способом и отрисовать нужный нам список постов.

import { Suspense } from "react";

export default function PostsPage() {
  const posts = getAllPostsMeta();
  const tags = getAllTags();

  return (
    <>
      // ...
      <Suspense fallback={<StaticPosts posts={posts} tags={tags} />}>
        <DynamicPosts posts={posts} tags={tags} />
      </Suspense>
      // ...
    </>
  );
}

Заметьте что компонент DynamicPosts обёрнут в Suspense. Фоллбек будет отрендерен в build-time. А компонент DynamicPosts будет отрендерен уже во время исполнения кода страницы на клиенте.

"use client"

// ...

const DynamicPage: React.FC<Props> = ({ posts, tags }) => {
  const searchParams = useSearchParams();

  const page = Number(searchParams.get("page")) || 1;
  const maxPage = Math.ceil(posts.length / POSTS_PER_PAGE);

  const pageOffset = (page - 1) * POSTS_PER_PAGE;

  const pagePosts = posts.slice(pageOffset, pageOffset + POSTS_PER_PAGE);

  if (!pagePosts.length) return notFound();

  return (
    <>
      <Posts posts={pagePosts} title={"Посты"} withFilter tags={tags} />
      <PageSelector page={page} maxPage={maxPage} />
    </>
  );
};

Для навигационного компонента, будем использовать компонент Link из встроенного пакета next/link и прокидывать в параметр href необходимую нам страницу.

<Link href={`./?page=${page}`}>{page}</Link>

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

Навигационный компонентНавигационный компонент

Работа над поисковой выдачей

Для того чтобы не получить дублирующиеся страницы в поиске, и не усложнить себе жизнь долгим процессом удалением дублей, необходимо сделать следующее:

Добавление ссылки на каноническую страницу

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

<link rel="canonical" href="https://baranov.guru/posts" />

В Next.js есть специальное Metadata API, которое можно использовать как раз для этих целей.

Воспользуемся им:

export const metadata: Metadata = {
  title: "Посты | Алексей Баранов. Блог",
  description: "Страница со всеми опубликованными постами",
  alternates: {
    canonical: `/posts`,
  },
};

Добавление директивы Clean-Param в robots.txt

Яндекс поддерживает специальную директиву Clean-param в файлах robots.txt.

Давайте добавим её:

User-agent: Yandex
Clean-param: page
Allow: /

На этом всё! 🎉

Расскажите о вашем проекте

Связаться иначе

Вам может быть интересно

Добавляем кнопку для сбора пожертвований (донатов) к блогу
Добавляем кнопку для сбора пожертвований (донатов) к блогу

Добавляем кнопку для сбора пожертвований (донатов) к блогу

6 мин.

Инструкция по добавлению кнопки для сбора пожертвований (донатов) к блогу...

Пост#туториалы
Как посчитать время чтения текста (и добавить индикатор на сайт)
Как посчитать время чтения текста (и добавить индикатор на сайт)

Как посчитать время чтения текста (и добавить индикатор на сайт)

4 мин.

Инструкция по добавлению индикатора времени чтения текста на сайт...

Пост#туториалы
Добавляем поиск по тегам в статический блог на Next.js
Добавляем поиск по тегам в статический блог на Next.js

Добавляем поиск по тегам в статический блог на Next.js

5 мин.

Инструкция по добавлению простейшего поиска по тегам в статическом Next.js блоге...

Пост#туториалы#nextjs
Подключение счётчика Яндекс Метрики к Next.js приложению
Подключение счётчика Яндекс Метрики к Next.js приложению

Подключение счётчика Яндекс Метрики к Next.js приложению

13 мин.

Инструкция по добавлению счётчика Яндекс Метрики к Next.js блогу...

Пост#nextjs#yandex