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

Как создать блог на 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
Автор
Редакция

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

Исправить ошибку VLC «Ввод не может быть открыт»
Техподдержка

Исправить ошибку VLC «Ввод не может быть открыт»

Остановить автозагрузку приложений на Samsung
Руководство

Остановить автозагрузку приложений на Samsung

Тайм‑лапсы в Procreate: запись и экспорт
Рисование

Тайм‑лапсы в Procreate: запись и экспорт

Как скопировать DVD на Mac — защищённые и незашищённые диски
How-to

Как скопировать DVD на Mac — защищённые и незашищённые диски

Как хакеры взламывают автомобили и как защититься
Кибербезопасность

Как хакеры взламывают автомобили и как защититься

Тёмная тема в Google Maps на Android
Android.

Тёмная тема в Google Maps на Android