Установка next-mdx-remote с плагинами rehype, remark на Next.js 13
Next.js

Установка next-mdx-remote с плагинами rehype, remark на Next.js 13

Теги не заданы
Razilator

В данной статье мы рассмотрим установку next-mdx-remote для преобразования Markdown в JSX из получаемого API для вывода контента на нашем фронтенде. Мы будем использовать последнюю версию Next.js 13, и добавим пару популярных плагинов от reHype, reMark.

Перед прочтений этой статьи, у вас должно быть API с которого поступает контент с markdown элементами (например описание статьи), либо настроенное хранилище с файлами mdx в Next.js со статями, откуда необходимо вывести форматированный контент.

Установка next-mdx-remote на Next.js 13

Устанавливаем модуль next-mdx-remote следующей командой в терминале вашего проекта: npm i next-mdx-remote. На момент написания статьи, версия: next-mdx-remote 4.4.1.

Настройка форматирования next-mdx-remote в Next.js 13

Ниже представлен пример использования компилятора compileMDX из модуля next-mdx-remote для форматирования контента детальной статьи, при получении данных из API:

lib/getArticles.js
import {compileMDX} from "next-mdx-remote/rsc";

export const getArticleBySlug = async (slug) => {
    const res = await fetch(`http://localhost:8000/articles/${slug}/`)
    const article = await res.json()
    const {frontmatter, content} = await compileMDX({
        source: article.description,
        components: components,
        options: {
            parseFrontmatter: false, // ставим true, если нам нужно собирать мета данные из файлов mdx (в моём случае данные приходят из API)
        }
    })
    return {article, content}
}

Пояснение: что я получаю по адресу localhost:8000? По этому адресу я получаю данные по API о детальной статье в следующем виде:

API
{
    "title": "Измерение длины объектов с помощью функции len() в Python",
    "slug": "measuring-the-length-of-objects-with-the-len-function-in-python",
    "description": "В **Python** функция `len()` предоставляет удобный способ измерить длину различных объектов.,
}

Подключение плагинов rehype, remark в next-mdx-remote

Модули rehype-figure, rehype-prism-plus, rehype-code-titles и remark-gfm являются плагинами для обработки и преобразования разметки текста в формате Markdown или HTML.

  • rehype-figure - это плагин для обработки тегов figure и figcaption. Он позволяет создавать и вставлять подписи к изображениям или другим медиа-элементам в HTML-контенте.
  • rehype-prism-plus - это плагин для подсветки синтаксиса кода с использованием библиотеки Prism. Он позволяет выделить и раскрасить код различных языков программирования, делая его более читабельным и понятным.
  • rehype-code-titles - это плагин, который добавляет заголовки к блокам кода в HTML-контенте. Это может быть полезно для идентификации и организации различных фрагментов кода на веб-странице.
  • remark-gfm - это плагин для разметки текста в формате GFM (GitHub Flavored Markdown). Он расширяет возможности обработки Markdown-разметки, добавляя поддержку таких функций, как таблицы, задачи списков, ссылки на пользователей и многое другое.

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

Давайте установим перечисленные модули, вводим в терминале следующую команду: npm i rehype-figure rehype-prism-plus rehype-code-titles remark-gfm

Теперь подключим данные модули, модернизировав код, который был расписан выше:

lib/getArticles.js
import remarkGfm from "remark-gfm";
import rehypeCodeTitles from "rehype-code-titles";
import rehypeFigure from "rehype-figure";
import rehypePrismAll from "rehype-prism-plus";

import {compileMDX} from "next-mdx-remote/rsc";

export const getArticleBySlug = async (slug) => {
    const res = await fetch(`http://localhost:8000/articles/${slug}/`)
    const article = await res.json()
    const {frontmatter, content} = await compileMDX({
        source: article.description,
        components: components,
        options: {
            parseFrontmatter: false, // ставим true, если нам нужно собирать мета данные из файлов mdx (в моём случае данные приходят из API)
            mdxOptions: {
                rehypePlugins: [rehypeCodeTitles, rehypePrismAll, rehypeFigure],
                remarkPlugins: [remarkGfm]
            }
        }
    })
    return {article, content}
}

Получение отформатированного контента в серверном компоненте

Далее мы можем получить article и content из функции getArticleBySlug() в серверном копоненте детальной страницы app/articles/[slug]/page.js:

app/articles/[slug]/page.js
import {getArticleBySlug} from "@lib/getArticles";
import ArticleDetailCard from "@components/Article/Detail/ArticleDetailCard";

export default async function ArticleDetailPage({ params: { slug } }) {
    // Получаем детальную статью с форматированным контентом
    const {article, content} = await getArticleBySlug(slug)
    // Выводим полную карточку статьи, передаем форматированный контент
    return <ArticleDetailCard article={article} content={content}/>;
}

export async function generateMetadata({ params: { slug } }) {
    // Генерируем мета-данные детальной статьи
    const {article} = await getArticleBySlug(slug)
    return {
        title: article.title,
        keywords: article.meta_keywords,
        description: article.description,
    }
}

Далее мы передаем одну статью, а также уже отформатированное описание статьи пропсами в компонент ArticleDetailCard.

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

components/Article/Detail/ArticleDetailCard
export default function ArticleDetailCard({ article, content }) {
    return (
        <article className="card">
            <div className="card-title">
                <h2>{article.title}</h2>
            </div>
            <div className="card-description">
                {content}
            </div>
        </article>
    );
}

Таким образом вы настроите форматирование контента статьи с помощью next-mdx-remote с использованием плагинов remark и rehype. Пример такого использования вы можете видеть в данной статье на нашем сайте proghunter!

;