Гид по технологиям

Как создать блог на Next.js, который рендерит Markdown

6 min read Web开发 Обновлено 29 Dec 2025
Блог на Next.js из Markdown — руководство
Блог на Next.js из Markdown — руководство

Крупный план печатной машинки

Коротко: Next.js — это React-фреймворк для рендеринга и сборки. Markdown — простой текстовый формат для статей. Вместе они позволяют быстро сделать статический блог с контролем над контентом и выводом.

В этом материале вы найдете пошаговые инструкции, готовые шаблоны кода и операционные чеклисты для разработки, тестирования и развёртывания блога на Next.js, который читает статьи из локальной папки в формате Markdown.

Зачем это делать и когда не стоит

  • Подходит, если вы хотите хранить статьи в Git и иметь полный контроль над шаблонами и рендерингом.
  • Не подходит, если вам нужна панель управления для авторов без доступа к репозиторию — в этом случае лучше Headless CMS (Strapi, Sanity, Contentful) или готовые платформы (WordPress, Ghost).

Важно: Markdown хорош для простого контента. Если нужны интерактивные компоненты внутри постов, рассмотрите MDX.

Основные термины

  • Markdown: лёгкий формат разметки для текста.
  • Front matter: YAML-метаданные в начале файла Markdown (title, date, tags и т. п.).
  • getStaticProps / getStaticPaths: функции Next.js для статической генерации.

Что потребует проект (технические требования)

  • Node.js (рекомендую LTS — 16+).
  • npm или Yarn.
  • Next.js (create-next-app упростит старт).

1. Создание проекта Next.js

Запустите в терминале:

npx create-next-app markdown-blog

Это создаст каркас приложения. После завершения удалите лишний код из страницы /pages/index.js и оставьте минимальную структуру.

Пример минимального index.js:

import Head from 'next/head'
import styles from '../styles/Home.module.css'

export default function Home() {
  return (
    
Create Next App
) }

2. Структура контента и файлы Markdown

Создайте в корне папку content (или posts). В ней будут храниться файлы .md.

Пример файла content/create-active-link-nextjs.md:

---
title: How To create an active link in Nextjs
description: Customizing active links using useRouter()
isPublished: true
publishedDate: 2022/07/22
tags:
  - next
---

## Main content

Советы по именованию:

  • Имя файла станет частью URL (slug). Используйте короткие и понятные имена без пробелов.
  • Дата в front matter может быть в формате YYYY-MM-DD или любой другой читаемой форме.

3. Установка зависимостей для парсинга Markdown

Установите react-markdown и gray-matter:

npm install react-markdown gray-matter

Кратко:

  • gray-matter парсит front matter (YAML) и возвращает объект meta + content.
  • react-markdown рендерит Markdown в React-компоненты безопасно.

4. Утилиты для работы с файлами Markdown

Создайте папку utils и файл utils/md.js. В нём разместите вспомогательные функции для чтения файлов, получения списка постов и содержимого.

Пример utils/md.js:

import fs from "fs";
import path from "path";
import matter from "gray-matter";

export const getPath = (folder) => {
  return path.join(process.cwd(), `/${folder}`); // полный путь к папке
}

export const getFileContent = (filename, folder) => {
  const POSTS_PATH = getPath(folder)
  return fs.readFileSync(path.join(POSTS_PATH, filename), "utf8");
};

export const getAllPosts = (folder) => {
  const POSTS_PATH = getPath(folder)

  return fs
    .readdirSync(POSTS_PATH)  // получить файлы в директории
    .filter((p) => /\.md?$/.test(p))  // только .md файлы
    .map((fileName) => {  // обработать каждый файл
      const source = getFileContent(fileName, folder);  // содержимое файла
      const slug = fileName.replace(/\.md?$/, "");  // slug = имя файла без расширения
      const { data } = matter(source);  // front matter
      return {
        frontmatter: data,
        slug: slug,
      };
    });
};

export const getAllPublished = (folder) => {
  const posts = getAllPosts(folder)

  const published = posts.filter((post) => {
    return post.frontmatter.isPublished === true
  })

  return published
}

export const getSinglePost = (slug, folder) => {
  const source = getFileContent(`${slug}.md`, folder);
  const { data: frontmatter, content } = matter(source);

  return {
    frontmatter,
    content,
  };
};

Пояснения:

  • getAllPosts возвращает массив { frontmatter, slug } для каждой Markdown-статьи.
  • getAllPublished фильтрует только опубликованные записи по ключу isPublished.
  • getSinglePost возвращает frontmatter и raw content статьи по slug.

5. Отображение списка статей (index)

Next.js генерирует страницы статически с помощью getStaticProps. В index вы получите список опубликованных постов и отрисуете их.

Пример /pages/index.js:

import Head from "next/head";
import Link from "next/link";
import { getAllPublished } from "../utils/md";
import styles from '../styles/Home.module.css'

function Home({ posts }) {
  return (
    
Create Next App
{posts.map((post) => ( ))}
); } export const getStaticProps = async () => { const posts = getAllPublished("content"); return { props: { posts }, }; }; export default Home;

Примечание: убедитесь, что путь в getAllPublished соответствует папке контента (content или posts).

6. Динамические маршруты и отображение одной статьи

Создайте страницу /pages/posts/[slug].js. Для статической генерации нужны getStaticPaths и getStaticProps.

Пример getStaticPaths и getStaticProps:

import { getAllPublished, getSinglePost } from "../../utils/md";

export const getStaticPaths = async () => {
  const paths = getAllPublished("content").map(({ slug }) => ({ params: { slug } }));

  return {
    paths,
    fallback: false,
  };
};

export const getStaticProps = async ({ params }) => {
  const post = await getSinglePost(params.slug, "content");

  return {
    props: { ...post },
  };
};

Компонент для рендера поста с react-markdown:

import ReactMarkdown from 'react-markdown'

const Post = ({ content, frontmatter }) => {
  return (
    

{frontmatter.tags.join(', ')}

{frontmatter.title}

{frontmatter.publishedDate} {content}
); }; export default Post;

7. Подсветка синтаксиса и расширения Markdown

Если нужны кодовые блоки с подсветкой:

  • Используйте rehype-прослойки (rehype-highlight) или prismjs вместе с rehype.
  • Для полноценной интеграции компонентов внутри Markdown используйте MDX (next-mdx-remote или @next/mdx).

Короткое сравнение:

  • react-markdown — простой и безопасный рендеринг Markdown.
  • MDX — позволяет вставлять React-компоненты прямо в Markdown.
  • Headless CMS — убирает необходимость редактировать репозиторий: контент хранится в UI.

8. Стилизация

Варианты:

  • CSS-модули (по умолчанию в Next.js). Хорошо для компонентной стилизации.
  • styled-components / emotion — CSS-in-JS для динамических стилей.
  • Глобальные CSS-файлы для стилизации Markdown-контента (например, .markdown-content h2, p, code).

Совет: задайте единый контейнер .markdown и применяйте типографику и отступы для всех элементов.

9. SEO и Open Graph

  • Используйте Head из next/head для задания title, meta description и Open Graph.
  • Для постов в front matter храните краткое описание (description) и изображение (ogImage).

Пример вставки metadata в компонент поста:

import Head from 'next/head'


  {frontmatter.title} — Мой блог
  
  
  

10. Тестирование и критерии приёмки

Критерии приёмки:

  • Список постов корректно рендерится на главной странице.
  • Каждая статья доступна по корректному урлу /posts/:slug.
  • Статья рендерит front matter (title, date, tags) и содержимое Markdown.
  • Для несуществующего slug возвращается 404 (fallback: false).

Тестовые сценарии:

  • Создать файл в content, отметить isPublished: true, запустить сборку — проверить появление на главной.
  • Установить isPublished: false — пост не должен отображаться.
  • Добавить кодовый блок и проверить подсветку (если включено).

11. Развёртывание и оптимизация

  • Статическая сборка Next.js отлично подходит для Vercel, Netlify, любой платформы, поддерживающей статические сайты.
  • Для больших блогов с сотнями постов подумайте про инвалидацию кэша при новых публикациях или переход на ISR (Incremental Static Regeneration).

12. Варианты расширения (альтернативные подходы)

  • MDX: для вставки React-компонентов в статьи.
  • Headless CMS: если нужен редактор для контент-менеджеров.
  • Git-backed CMS (Netlify CMS, TinaCMS): управлять контентом через интерфейс, хранить в Git.
  • Полный статический генератор (Hugo, Jekyll) — быстрее сборка, но меньше гибкости React.

13. Уровни зрелости решения

  • MVP: локальная папка content + react-markdown + gray-matter.
  • Средний: добавить подсветку, SEO-мета, пагинацию, теги.
  • Про: MDX, headless CMS, CI-пайплайн, ISR, интеграция аналитики и AMP (опционально).

14. Роли и чек-листы

Разработчик:

  • Настроить файл utils/md.js и маршруты.
  • Реализовать шаблон поста (шрифты, типографика).
  • Настроить подсветку кода.

Контент-редактор:

  • Писать статьи в Markdown с front matter.
  • Проверять формат даты и теги.

Ops / DevOps:

  • Настроить CI для билдов.
  • Настроить развёртывание на Vercel/Netlify.

15. Частые ошибки и как их исправлять

  • Неправильный путь к папке content: проверьте process.cwd() и путь в getPath.
  • Ошибки парсинга front matter: проверьте корректность YAML (отступы, дефисы).
  • Некорректные slugs: проверьте, что имя файла не содержит пробелов и специальных символов.

16. Примеры команд и полезные шаблоны

Сборка и запуск локально:

npm run dev
npm run build
npm start

Пример front matter для поста с ogImage:

---
title: Пример статьи
description: Краткое описание статьи
isPublished: true
publishedDate: 2025-01-10
tags:
  - nextjs
  - markdown
ogImage: /images/og-image.png
---

Контент поста...

17. Короткий план внедрения (roadmap)

  1. Создать каркас Next.js и папку content.
  2. Реализовать utils/md.js и basic pages.
  3. Добавить react-markdown и проверить рендеринг.
  4. Подключить подсветку кода и MDX при необходимости.
  5. Настроить CI и развернуть на Vercel.

18. Пример принятия решения: использовать MDX или нет

  • Если вам нужны компоненты в статьях — MDX.
  • Если нужны только тексты и простая разметка — react-markdown.

Mermaid диаграмма принятия (если нужна визуализация):

flowchart TD
  A[Нужны React-компоненты в статьях?] -->|Да| B[Использовать MDX]
  A -->|Нет| C[Использовать react-markdown]
  B --> D[Добавить поддержку компиляции MDX]
  C --> E[Добавить rehype/remark плагины при необходимости]

19. Безопасность и приватность

  • Не рендерите небезопасный HTML напрямую без санитайза.
  • Проверяйте загружаемые пути для изображений (чтобы предотвратить SSRF в редких конфигурациях).
  • Если вы храните персональные данные в постах, учитывайте требования локального законодательства по хранению и удалению данных.

20. Краткое резюме

  • Next.js + Markdown — быстрый путь к собственному блогу с полным контролем.
  • react-markdown + gray-matter — базовая связка для рендеринга и парсинга.
  • Для более сложных задач используйте MDX или Headless CMS.

Важное: начните с минимального набора, затем постепенно добавляйте подсветку, SEO и CI. Это снизит риски и ускорит обратную связь.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

RDP: полный гид по настройке и безопасности
Инфраструктура

RDP: полный гид по настройке и безопасности

Android как клавиатура и трекпад для Windows
Гайды

Android как клавиатура и трекпад для Windows

Советы и приёмы для работы с PDF
Документы

Советы и приёмы для работы с PDF

Calibration в Lightroom Classic: как и когда использовать
Фото

Calibration в Lightroom Classic: как и когда использовать

Отключить Siri Suggestions на iPhone
iOS

Отключить Siri Suggestions на iPhone

Рисование таблиц в Microsoft Word — руководство
Office

Рисование таблиц в Microsoft Word — руководство