Посты и пагинация

MDX (Markdown + JSX) позволяет сочетать возможности Markdown для разметки текста с компонентами React, что делает её особенно удобной для генерации контента в веб-приложениях. Основным строительным блоком является MDX-файл, который представляет собой отдельный пост или страницу. Каждый файл может содержать как обычный Markdown, так и встроенные React-компоненты, что делает его гибким инструментом для создания интерактивного контента.

Структура MDX-поста обычно включает:

  • Метаданные (frontmatter) — YAML-блок в начале файла, определяющий свойства поста, такие как title, date, author, tags и другие. Пример:
---
title: "Пагинация в MDX"
date: "2026-03-23"
author: "Иван Иванов"
tags: ["MDX", "JavaScript", "React"]
---
  • Основной контент — текст в Markdown с возможностью вставки JSX-компонентов.
## Введение в пагинацию

Пагинация используется для удобного отображения большого количества постов.  
Компоненты React позволяют динамически создавать навигацию между страницами.

Импорт и использование постов

MDX-файлы обычно импортируются как модули в JavaScript-проектах. В современных приложениях с использованием Next.js или Vite это делается через ESM-импорт или динамическую загрузку.

Пример импорта:

import Post1 from './posts/post1.mdx';
import Post2 from './posts/post2.mdx';

const posts = [Post1, Post2];

После импорта посты можно использовать как обычные React-компоненты:

function Blog() {
  return (
    <div>
      {posts.map((Post, index) => (
        <Post key={index} />
      ))}
    </div>
  );
}

Организация пагинации

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

Основные шаги создания пагинации:

  1. Разделение постов на страницы. Определяется количество постов на одной странице:
const POSTS_PER_PAGE = 5;
const totalPages = Math.ceil(posts.length / POSTS_PER_PAGE);

function getPostsByPage(page) {
  const start = (page - 1) * POSTS_PER_PAGE;
  const end = start + POSTS_PER_PAGE;
  return posts.slice(start, end);
}
  1. Создание навигации между страницами. Можно использовать обычные ссылки или компоненты React:
function Pagination({ currentPage, totalPages }) {
  return (
    <nav>
      {currentPage > 1 && (
        <a href={`/blog/page/${currentPage - 1}`}>Предыдущая</a>
      )}
      {currentPage < totalPages && (
        <a href={`/blog/page/${currentPage + 1}`}>Следующая</a>
      )}
    </nav>
  );
}
  1. Динамическая генерация страниц (для Next.js):
export async function getStaticPaths() {
  const totalPages = Math.ceil(posts.length / POSTS_PER_PAGE);
  const paths = Array.from({ length: totalPages }, (_, i) => ({
    params: { page: `${i + 1}` },
  }));
  return { paths, fallback: false };
}

export async function getStaticProps({ params }) {
  const page = parseInt(params.page, 10);
  const pagePosts = getPostsByPage(page);
  return { props: { pagePosts, page } };
}

Использование MDX для динамического контента

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

Пример использования компонента внутри MDX:

<LikeButton postId="post-1" />

## Раздел с кодом

```javascript
console.log("Пример кода");

Благодаря этому подходу контент становится более динамичным и гибким, а пагинация не теряет своих преимуществ — страницы остаются лёгкими, а интерфейс — отзывчивым.

---

### Рекомендации по оптимизации

- Для больших проектов рекомендуется хранить **метаданные постов отдельно**, чтобы можно было быстро получать список постов без загрузки всего контента.
- Использование **динамического импорта** для MDX-файлов снижает начальную загрузку страницы.
- Посты с интерактивными компонентами следует **разделять по функциональным блокам**, чтобы избежать избыточного рендера.

---

### Итоговая структура проекта с пагинацией

/posts post1.mdx post2.mdx post3.mdx /pages blog [page].js /components Pagination.jsx LikeButton.jsx /lib posts.js


Файл `posts.js` отвечает за загрузку и сортировку MDX-файлов, `[page].js` — за генерацию страниц с пагинацией, а компоненты — за интерактивные элементы. Такой подход позволяет легко масштабировать блог и добавлять новые функции без значительных изменений кода.