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

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

6 min read Веб-разработка Обновлено 05 Jan 2026
Блог на Next.js с Markdown
Блог на Next.js с Markdown

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

Зачем собирать блог вручную

Low-code инструменты (например, WordPress) упрощают запуск блога — готовые темы и интерфейсы позволяют писать посты за часы. Но если вам важен контроль над кодом, производительностью и структурой контента, стоит сделать блог с нуля. Next.js даёт готовые механизмы для статической генерации и интеграции React-компонентов, что упрощает работу с Markdown.

Важно: “фронт‑маттер“ — это YAML‑блок в начале Markdown‑файла, где задаются метаданные поста (заголовок, дата, теги и т. д.).

Что потребуется

  • Node.js (LTS) и npm или yarn
  • Базовые знания React и Next.js
  • Папка проекта, структура с корнем проекта
  • Пакеты: react-markdown и gray-matter

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

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

Самый простой способ стартовать — выполнить в терминале:

npx create-next-app markdown-blog  

Это создаст проект со всем необходимым каркасом. Очистите файл index.js, чтобы он выглядел лаконично — в примере ниже показан минимальный шаблон (сохраните его в проекте):

import Head from 'next/head'  
import styles from '../styles/Home.module.css'  
  
export default function Home() {  
  return (  
      
        
        Create Next App  
          
          
        
    
) }

Структура контента и формат Markdown

Создайте в корне проекта папку content (или posts) для хранения Markdown‑файлов. Каждый файл будет отдельным постом, а имя файла — частью URL.

Пример файла: 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  

Обратите внимание на блок между строками с трёхточиями — это фронт‑маттер. Поле isPublished удобно для фильтрации постов на этапе сборки.

Установка библиотек для парсинга

Для парсинга Markdown и фронт‑маттера установите:

npm install react-markdown gray-matter  
  • react-markdown — компонент, который безопасно конвертирует Markdown в React/HTML.
  • gray-matter — парсер фронт‑маттера (YAML → объект).

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

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

Код (пример):

import fs from "fs";  
import path from "path";  
import matter from "gray-matter";  
  
export const getPath = (folder:string) => {  
    return path.join(process.cwd(), `/${folder}`); // Get full path   
}  
  
export const getFileContent = (filename:string, folder:string) => {  
    const POSTS_PATH = getPath(folder)  
    return fs.readFileSync(path.join(POSTS_PATH, filename), "utf8");  
};  
  
export const getAllPosts = (folder:string) => {  
  const POSTS_PATH = getPath(folder)  
  
  return fs  
    .readdirSync(POSTS_PATH)  // get files in directory  
    .filter((path) => /\.md?$/.test(path))  // only .md files  
    .map((fileName) => {  // map over each file  
      const source = getFileContent(fileName, folder);  // retrieve the file contents  
      const slug = fileName.replace(/\.md?$/, "");  // get the slug from the filename  
      const { data } = matter(source);  // extract frontmatter  
      return {  
        frontmatter: data,  
        slug: slug,  
      };  
    });  
};  

Пояснения к функциям:

  • getPath — возвращает абсолютный путь к папке с контентом.
  • getFileContent — читает файл и возвращает его содержимое как строку.
  • getAllPosts — считывает все .md‑файлы в папке, извлекает фронт‑маттер и формирует массив объектов { frontmatter, slug }.

Фильтрация опубликованных постов

Чтобы возвращать только посты с isPublished: true, используйте фильтр:

export const getAllPublished = (folder:string) => {  
    const posts = getAllPosts(folder)  
  
    const published = posts.filter((post) => {  
      return post.frontmatter.isPublished === true  
    })  
  
    return published  
  }  

Этот helper полезен для отображения списка постов в домашней странице.

Получение одного поста

Добавьте функцию для извлечения полного содержимого поста (фронт‑маттер + тело Markdown):

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

Эта функция считывает файл по slug и возвращает frontmatter и raw Markdown (content).

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

Next.js поддерживает статическую генерацию. getStaticProps вызывается во время сборки и возвращает props компоненту страницы.

Пример использования getStaticProps и перечисления постов:

export const getStaticProps = async () => {  
  const posts = getAllPublished("posts");  
  
  return {  
    props: { posts },  
  };  
};  

Измените компонент Home, чтобы он отображал список постов:

import Head from "next/head";  
import Link from "next/link";  
import { getAllPublished } from "../utils/md";  
  
function Home({ posts }) {  
  return (  
      
        
        Create Next App  
          
          
        
      
{posts.map((post) => (

[ {post.frontmatter.tags.join(", ")} ]

{post.frontmatter.title} {" "}

{post.frontmatter.description}

))} ); } export const getStaticProps = async () => { const posts = getAllPublished("content"); return { props: { posts }, }; }; export default Home;

Примечание: в примере getAllPublished вызывается с аргументом “content” — используйте имя папки, где вы реально храните свои .md‑файлы.

Генерация динамических маршрутов и отображение поста

Для генерации путей используйте getStaticPaths, а затем getStaticProps для каждого пути.

export const getStaticPaths = async () => {  
  const paths = getAllPublished("posts").map(({ slug }) => ({ params: { slug } }));  
  
  return {  
    paths,  
    fallback: false,  
  };  
};  

Затем — получение данных для конкретного поста:

export const getStaticProps = async ({ params }) => {  
  const post = await getSinglePost(params.slug, "posts");  
  
  return {  
    props: { ...post },  
  };  
};  

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

import ReactMarkdown from 'react-markdown'  
import { getAllPosts, getSinglePost } from "../../utils/md";  
  
const Post = ({ content, frontmatter }) => {  
  return (  
    

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

{frontmatter.title}

{frontmatter.publishedDate} {content}
); };

Это отобразит заголовок, дату, теги и преобразованный HTML из Markdown.

Подсветка синтаксиса для dev‑постов

Для блога разработчика удобно добавить подсветку синтаксиса. Популярные варианты:

Примерный путь: подключить плагин в трансформer react‑markdown (rehypePlugins/remarkPlugins), и добавить CSS темы Prism.

Стилизация

Next.js поддерживает CSS-модули, глобальные CSS и CSS-in-JS. Для простоты можно использовать CSS‑модули: создайте файл styles/Blog.module.css и импортируйте его в компоненты.

Если нужна более богатая типографика для статей — используйте готовые типографические CSS (например, типографические наборы для article) или Tailwind CSS.

Альтернативные подходы

Когда ручное хранение Markdown может не подойти: нужна поддержка WYSIWYG для редакторов, права доступа и версионирование — тогда headless CMS удобнее.

Паттерны и ментальные модели

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

Чеклист перед деплоем

Ролевые чеклисты

Автор:

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

Операции/Мейнтейнер:

Точки отказа и способы защиты

Миграция и совместимость

Пример маленькой методологии публикации

  1. Автор создаёт .md в ветке feature/post-title.
  2. PR проходит ревью кода и контента.
  3. Мерж в main запускает CI сборку и деплой статической версии.
  4. Если нужна горячая корректировка — правка фронт‑маттера и повторный merge.

Короткая галерея крайних случаев

1‑строчная глоссарий

Последние рекомендации по SEO и social

Выгляд для социальных сетей (пример):

Короткое резюме

Важное: если ваш проект будет расти и появятся требования к редактированию контента через UI, рассмотрите внедрение headless CMS или MDX.

Поделиться: 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 — руководство