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

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

Добавляем подсветку кода (синтаксиса) в статический блог на Next.js
Дата публикации
15.06.24
Дата обновления
16.05.26
Время чтения
4 мин.

Продолжаем работать над улучшением блога. В этой статье расскажем как добавляли подсветку кода (синтаксиса) в постах.

Есть множество способов сделать это, мы же решили пойти самым простым путём и остановились на использовании пакета Prism.

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

Установка необходимых пакетов

Сначала установим необходимые пакеты:

npm i prismjs

Так как мы статически генерируем html блога из .md файлов, то нам нужен способ запускать Prism во время сборки приложения. В этом нам поможет пакет rehype-prism.

npm i rehype-prism

Статическая генерация подсвеченного кода

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

import "prismjs";
import rehypePrism from "rehype-prism";
import rehypeStringify from "rehype-stringify";
import remarkCustomHeaderId from "remark-custom-header-id";
import remarkParse from "remark-parse";
import remarkRehype from "remark-rehype";
import { unified } from "unified";

export default async function markdownToHtml(markdown: string) {
  const result = unified()
    .use(remarkParse, { sanitize: false })
    .use(remarkCustomHeaderId)
    .use(remarkRehype)
    // Внимание на следующую строку
    .use(rehypePrism)
    .use(rehypeStringify)
    .process(markdown);

  return (await result).toString();
}

Добавление подсветки необходимых языков

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

import "prismjs/components/prism-bash";
import "prismjs/components/prism-json";
import "prismjs/components/prism-typescript";

Работа с плагинами Prism

Так же Prism поддерживает множество плагинов. Мы выбрали "line-numbers", "toolbar", "copy-to-clipboard" плагины.

Для того чтобы их активировать необходимо:

Подключение кода и стилей этих плагинов

Добавим импорт стилей для плагинов в компонент Post.

import "prismjs/plugins/line-numbers/prism-line-numbers.css";
import "prismjs/plugins/toolbar/prism-toolbar.css";

Использование плагинов

Пакет rehype-prism поддерживает нужные нам плагины из коробки, необходимо только указать что их следует использовать.

export default async function markdownToHtml(markdown: string) {
  const result = unified()
    .use(remarkParse, { sanitize: false })
    .use(remarkCustomHeaderId)
    .use(remarkRehype)
    // Внимание на следующую строку
    .use(rehypePrism, {
      plugins: ["line-numbers", "toolbar", "copy-to-clipboard"],
    })
    .use(rehypeStringify)
    .process(markdown);

  return (await result).toString();
}

Подключение цветовой темы Prism

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

import "prismjs/themes/prism.css";

На этом всё! 🎉

Результат можно посмотреть в любом из постов блога.

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

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

Часто задаваемые вопросы

Блоки кода в Markdown без подсветки читаются хуже. Prism раскрашивает синтаксис уже на этапе сборки — в HTML попадает готовая разметка, без тяжёлого рантайма на клиенте.

В статье выбран простой путь: prismjs + rehype-prism в цепочке unified при конвертации .md → HTML. Другие движки тоже подходят.

prismjs — движок подсветки, rehype-prism — плагин для rehype во время сборки. Плюс unified, remark/rehype — как в разделе установка и генерация.

Языки в Prism подключаются отдельно: импортируйте prismjs/components/prism-… для каждого языка (bash, json, typescript и т.д.). См. добавление языков.

Плагины line-numbers, toolbar, copy-to-clipboard: импорт CSS в компонент поста и опция plugins у rehypePrism. Подробности — плагины Prism.

Импортируйте CSS темы из prismjs/themes/ (например prism.css) в компонент, который рендерит статью. Раздел подключение темы.

Статья описывает пайплайн Markdown → HTML. Если блог на MDX, подсветку настраивают в своём процессоре — см. MDX в Next.js. Проверка орфографии в черновиках — markdown-spellcheck.

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

Добавляем поддержку MDX в Next.js приложение
Добавляем поддержку MDX в Next.js приложение

Добавляем поддержку MDX в Next.js приложение

3 мин.

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

Пост#nextjs
Борьба с грамматическими ошибками в markdown файлах
Борьба с грамматическими ошибками в markdown файлах

Борьба с грамматическими ошибками в markdown файлах

3 мин.

Инструкция по использованию LTеX для борьбы с грамматическими ошибками в .md файлах...

Пост#инструменты
Добавляем RSS-фид к статическому Next.js приложению
Добавляем RSS-фид к статическому Next.js приложению

Добавляем RSS-фид к статическому Next.js приложению

5 мин.

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

Пост#nextjs#фиды
Автоматизируем публикацию npm-пакета с помощью Github Actions
Автоматизируем публикацию npm-пакета с помощью Github Actions

Автоматизируем публикацию npm-пакета с помощью Github Actions

7 мин.

Инструкция по подготовке npm-пакета к автоматизированному релизу с помощью Github Actions...

Пост#DevOps#github
Брендированные типы (branded types) в TypeScript
Брендированные типы (branded types) в TypeScript

Брендированные типы (branded types) в TypeScript

4 мин.

Что такое branded types в Typescript и как с их помощью улучшить type safety в рантайме...

Пост#typescript
Добавляем рекомендации постов и блок "Поделиться в соц. сетях"
Добавляем рекомендации постов и блок "Поделиться в соц. сетях"

Добавляем рекомендации постов и блок "Поделиться в соц. сетях"

4 мин.

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

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

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

4 мин.

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

Пост#туториалы
Frontend разработка
Frontend разработка

Frontend разработка

Разрабатываем интерфейсы, которые быстро работают, удобно используются и масштабируются вместе с продуктом.

Услуга#frontend#веб-разработка
Разработка вебсайтов
Разработка вебсайтов

Разработка вебсайтов

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

Услуга#веб-разработка#сайты