Публикация статического контента становится такой простой с помощью MDX и Contentlayer. Я покажу вам, как

TL;DR

  • 💨 Contentlayer уменьшает количество трений при публикации контента на моем статическом веб-сайте.
  • 😍 MDX с плагинами для замечаний и репостов невероятно удобен и мощен.
  • 🍵 Next.js отлично сочетается с Contentlayer и MDX.

Я полностью внедрил Генерацию статического сайта (SSG) для своего веб-сайта, чтобы оптимизировать скорость и масштабирование сайта в будущем.

Недавно я исследовал, как уменьшить усилия по созданию новой статьи на моем веб-сайте. В моей настройке проекта Next.js было много точек соприкосновения, чтобы:

  • опубликовать новую статью
  • оценить время чтения
  • обновить список статей
  • создать новую RSS-ленту
  • обновить карту сайта

В чем была проблема?

Я еще немного проанализировал и обнаружил, что проблема заключалась в использовании MDX. Моя файловая структура выглядела так:

my-blog
├── public
├── data
│   └── blogs.json
├── components
│   └── Blog.tsx
└── pages
    ├── blogs
    │   ├── blog-one.mdx
    │   ├── blog-two.mdx
    │   └── blog-three.mdx
    └── index.tsx

Это стандартная установка, рекомендованная Next.js. Я использовал @mdx-js/loader и @next/mdx для преобразования MDX в страницы.

Возьмем, к примеру, pages/blogs/blog-one.mdx, содержимое выглядело так:

blog-one.mdx назвал-экспортировал метаданные. Он был подобран компонентом по умолчанию, который заботился о макете и отображал метаданные.

Компонент <Blog /> выглядел так:

Я рассматривал файлы MDX как страницы.

Поскольку данные meta в каждом файле MDX были захвачены на странице, я продублировал все метаданные и объединил их в data/blogs.json. Я использовал его для ведения списка статей на своем веб-сайте, RSS-канала и карты сайта для SEO.

Было бы намного лучше, если бы я мог обрабатывать файлы MDX как данные и создавать страницы на основе этих данных.

Таким образом, я мог одновременно использовать файлы MDX в качестве точек данных и содержимого страницы. Публикация новой статьи в идеале могла бы быть намного проще.

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

Что такое контентный слой

Contentlayer — это библиотека на ранней стадии, которая превращает контент в данные. Это работает примерно так:

  • В качестве источника используется безголовая CMS или локальный контент в форматах YAML, JSON, MDX или Markdown.
  • Он преобразует содержимое в типы TypeScript и файлы данных в формате JSON, включая исходное содержимое, метаданные и любые указанные нами производные данные.
  • Он собирает все данные в формате JSON и экспортирует их как ESM.

В моем случае я могу использовать агрегированные данные, сгенерированные Contentlayer, чтобы заменить мой предыдущий ручной процесс:

  • Я использую сгенерированные данные для создания новой страницы для статьи.
  • Я использую сгенерированные данные для рендеринга списка статей.
  • Я использую сгенерированные данные для создания нового RSS-канала.
  • Я использую новую файловую структуру для создания новой карты сайта.
  • Все автоматически!

Contentlayer предлагает простую интеграцию с Next.js. Я покажу вам, как в следующих разделах.

Использование MDX в качестве данных

Давайте сначала рассмотрим, как использовать MDX в качестве точки данных.

MDX предлагает поддержку YAML frontmatter с пользовательскими парсерами. Вы можете выразить метаданные следующим образом:

---
title: 'Blog One🚀'
publishedAt: 'February 4, 2022'
description: 'Learn how to build a Next.js blog with MDX and Contentlayer!'
cover: '/optimized/articles/blog-one/hero.webp'
---
Hey There👋
Welcome to Blog One✨ Let's learn together!

Вы можете видеть, что метаданные в синтаксисе YAML находятся внутри блока ---, а основная часть содержимого следует в синтаксисе MDX. По сравнению со старой настройкой, где файл MDX рассматривался как страница, новый файл MDX содержит только метаданные и контент.

Следующее, что нам нужно сделать, это сгенерировать страницу блога, которая отображает метаданные и контент с макетом из компонента <Blog />.

Интеграция Contentlayer в Next.js

Теперь, когда мы обновили файлы MDX, чтобы они содержали только данные и контент, давайте переместим их в каталог data.

Новая файловая структура выглядит так:

my-blog
├── public
├── components
│   └── Blog.tsx
├── pages
│   ├── blogs
│   │   └── [slug].tsx
│   └── index.tsx
└── data
    └──blogs
       ├── blog-one.mdx
       ├── blog-two.mdx
       └── blog-three.mdx

Обратите внимание, что мы заменили файлы MDX в каталоге pages/blogs на динамический маршрут [slug].tsx. Мы будем использовать эту страницу для статической генерации страниц блога позже.

Настройка слоя содержимого

Contentlayer предлагает бесшовную интеграцию с Next.js.

Чтобы установить зависимости:

yarn add contentlayer next-contentlayer

Contentlayer считывает конфигурацию из contentlayer.config.ts. Давайте создадим его.

touch contentlayer.config.ts

Внутри contentlayer.config.ts нам нужно добавить инструкции, чтобы сообщить Contentlayer, как парсить:

  • name: пространство имен
  • filePathPattern: входные файлы
  • bodyType: тип содержимого для разбора
  • fields: поля метаданных
  • computedFields: производные поля метаданных

В computedFields мы можем вычислять данные, такие как readingTime, из тела контента🤩. Я использую reading-time для расчета времени чтения на основе количества слов. Поле slug предназначено для создания динамического маршрута позже на странице [slug].tsx.

Под капотом Contentlayer использует mdx-bundler для синтаксического анализа переднего плана MDX и YAML и извлечения контента и данных. Если вас интересует магия, стоящая за этим, вы можете прочитать больше о gray-matter и remark-mdx-frontmatter. Это библиотеки, которые mdx-bundler использует внутри.

В конце настройки makeSource будет искать файлы, соответствующие шаблону blogs/*.mdx в каталоге data, и сгенерирует данные блога в каталоге .contentlayer в корне вашего проекта.

Наконец, оберните вашу конфигурацию Next.js next-contentlayer, чтобы интегрировать ее с процессом динамической перезагрузки и сборки Next.js.

Использование данных Contentlayer для создания статического сайта

Мы готовы использовать сгенерированные данные из Contentlayer и строить статические страницы🤩

Все, что нам нужно сделать, это использовать allBlogs из .contentlayer/data для построения динамических маршрутов с помощью getStaticPaths и использовать getStaticProps для передачи данных блога на страницу [slug].tsx.

После сборки проекта вы увидите блоги, доступные по адресам /blogs/blog-one, /blogs/blog-two и /blogs/blog-three✨.

Бонус: плагины для комментариев и репостов

С помощью MDX мы можем сделать гораздо больше, используя плагины для комментариев и репостов в файле contentlayer.config.ts.

  • remark — это потрясающая экосистема плагинов, которая трансформирует уценку.
  • rehype — еще одна мощная экосистема плагинов, преобразующая HTML.

Это две отдельные экосистемы, но мы можем преобразовать замечание в рехайп и создать HTML-разметку. Трансформация выглядит так:

MDX ----> remark AST ------> rehype AST --------> HTML
    parse            convert            stringify

Contentlayer заботится о потоке. Все, что нам нужно сделать, это добавить плагины, чтобы предоставить инструкции для преобразований. Я использую следующие плагины:

Приложения уровня контента

Есть еще вещи, которые мы можем сделать с данными.

Приложение №1: RSS-канал

Теперь я могу написать сценарий для создания базы RSS-канала на основе данных allBlogs!

Приложение № 2: XML-карта сайта

Проще написать скрипт для генерации карты сайта. Все, что нам нужно, это файловая структура в каталогах data и page.

Запустите оба скрипта после создания проекта и автоматически сгенерируйте новый RSS-канал и карту сайта.

В package.json добавьте:

"scripts": {
+    "sitemap": "node scripts/sitemap.mjs",
+    "rss": "node scripts/rss.mjs",
+    "postbuild": "yarn sitemap && yarn rss",
  },

Последние мысли

Создание статических сайтов с помощью Next.js становится таким простым благодаря многомерным выражениям и Contentlayer.

MDX сочетается с экосистемой замечаний, а повторная реклама расширяет возможности создания согласованных страниц с помощью Markdown. Contentlayer делает данные и содержимое в файлах MDX доступными для использования в проектах Next.js.

Если вы изучаете способы создания собственных статических сайтов, ознакомьтесь с упомянутыми ранее библиотеками. Это не только сокращает время выхода на рынок, но и доставляет массу удовольствия при сборке!🦄

Рекомендации

Want to Connect?
This article was originally posted on Daw-Chih’s website.