Управление контентом может быть утомительной и трудоемкой задачей, но что, если я скажу вам, что есть инструмент, который может упростить этот процесс и сделать его легким? Представляем Contentlayer, мощный инструмент, который преобразует ваш контент в данные и упрощает работу с файлами .md
и .mdx
. С Contentlayer все, что вам нужно сделать, это установить и настроить его, и вы можете начать писать в предпочитаемом формате файла. Лучшая часть? Contentlayer автоматически добавляет типы к вашим данным, гарантируя, что ваш контент всегда типобезопасен. Попрощайтесь с трудностями управления контентом и познакомьтесь с более оптимизированным процессом с Contentlayer и Next.js.
Настройка приложения Next.js
Чтобы создать приложение Next.js с серверными компонентами, мы будем использовать новую функцию appDir. Просто добавьте флаг —experimental-app в свою команду, и для вас будет создан новый каталог приложения. Стоит отметить, что все в этом каталоге по умолчанию будет считаться серверным компонентом.
Для начала выполните любую из следующих команд:
npx create-next-app@latest --experimental-app # or yarn create next-app --experimental-app # or pnpm create next-app --experimental-app
После того, как ваше приложение Next.js создано, рекомендуется очистить весь ненужный код, чтобы ваш проект был организован и эффективен.
Установить контентный слой
Чтобы использовать Contentlayer, вы должны установить пакет Contentlayer и плагин Next.js. Чтобы установить эти пакеты, выполните следующие команды:
npm install contentlayer next-contentlayer #or yarn add contentlayer next-contentlayer #or pnpm add contentlayer next-contentlayer
Конфигурация для Contentlayer
Чтобы интегрировать контентный слой в процессы next dev
и next build
, нам нужно обернуть nextConfig
методом withContentlayer
.
// next.config.js const { withContentlayer } = require('next-contentlayer'); /** @type {import('next').NextConfig} */ const nextConfig = { experimental: { appDir: true, }, }; module.exports = withContentlayer(nextConfig);
Кроме того, нам нужно обновить наш файл tsconfig.json или jsconfig.json со следующими изменениями:
{ "compilerOptions": { "baseUrl": ".", "paths": { "contentlayer/generated": ["./.contentlayer/generated"] } }, "include": ["next-env.d.ts", "**/*.tsx", "**/*.ts", ".contentlayer/generated"] }
Определение схемы публикации
Начнем с того, что расскажем о важности определения схемы поста для нашего блога. Эта схема поможет Contentlayer преобразовать наш контент в данные, которые можно использовать в нашем блоге. Чтобы создать эту схему, нам нужно создать новый файл с именем contentlayer.config.js в корне нашего проекта и включить следующий код:
import { defineDocumentType, makeSource } from 'contentlayer/source-files'; const Post = defineDocumentType(() => ({ name: 'Post', filePathPattern: `**/*.md`, fields: { title: { type: 'string', required: true, }, description: { type: 'string', required: true, }, keywords: { type: 'string', required: true, }, date: { type: 'string', required: true, }, }, computedFields: { url: { type: 'string', resolve: (doc) => doc._raw.flattenedPath, }, }, })); export default makeSource({ contentDirPath: 'posts', documentTypes: [Post], });
Этот код будет определять тип документа Post, который будет представлять наши сообщения в блоге. Предполагается, что каждое сообщение представляет собой файл .md, расположенный в каталоге сообщений. Эта схема будет включать следующие свойства:
title
: обязательная строка, которая будет использоваться в качестве заголовка сообщения в блоге.description
: обязательная строка, которая будет использоваться в качестве описания сообщения в блоге.date
: обязательная строка, которая будет использоваться в качестве даты сообщения в блоге.url
: вычисляемая строка, которая будет принимать имя файла без расширения и использоваться в качестве URL-адреса сообщения в блоге.
Важно отметить, что заголовок сообщения в блоге также будет использоваться в качестве h1 сообщения в блоге, поэтому никакие другие теги h1 не должны использоваться в содержании. Определив схему Post, мы можем легко преобразовать наш контент в данные, которые можно использовать в нашем блоге.
Добавить сообщения
Чтобы заполнить наш блог, нам нужно добавить некоторый контент. Начните с создания нового каталога с именем post и добавьте туда все свои сообщения.
Например, вот пример сообщения с названием what-is-contentlayer.md, расположенного в каталоге сообщений:
--- title: 'What is Contentlayer?' description: 'Demo description' keywords: 'content, preprocessor, type-safe' date: '2022-02-22' --- **Contentlayer makes working with content easy.** It is a content preprocessor that validates and transforms your content into type-safe JSON you can easily import into your application.
Важное примечание. Обязательно запустите среду разработки сейчас. Это создаст каталог .contentlayer, содержащий весь наш контент в формате .json. Это означает, что наш контент был преобразован в данные, что упрощает управление им.
Страница блогов
Чтобы продемонстрировать все наши сообщения в блоге, мы заменим домашнюю страницу (app/page.tsx
) следующим кодом:
import Link from 'next/link'; import { allPosts } from 'contentlayer/generated'; export const metadata = { title: 'Blog', description: 'Discover insights, tips, and techniques on web development.', openGraph: { title: 'Blog', description: 'Discover insights, tips, and techniques on web development.', siteName: 'Blog Website', locale: 'en-US', type: 'website', }, twitter: { title: 'Blog', description: 'Discover insights, tips, and techniques on web development.', }, }; export default function Home() { return ( <main> <h1>Blog</h1> {allPosts .sort((a, b) => { if (new Date(a.date) > new Date(b.date)) { return -1; } return 1; }) .map((post) => ( <Link key={post.url} href={`/blog/${post.url}`}> <p>{post.title}</p> </Link> ))} </main> ); }
Мы импортируем все наши сообщения в блоге из contentlayer/generated и отображаем их в виде ссылок, отсортированных по дате. Деструктурируя каждый объект публикации, мы можем легко получить доступ к его свойствам URL и заголовка.
Обратите внимание, что мы используем новую дату (b.date) — новую дату (a.date) вместо оператора if для сортировки сообщений в порядке убывания. Мы также переименовали компонент в Blog для ясности. Кроме того, мы включили метаданные для целей SEO, используя новый формат метаданных, доступный в next.js 13.
Создание единого макета поста в блоге
Чтобы отобразить каждый пост в блоге на отдельной странице, нам нужно создать страницу-слаг. Эта страница будет использовать определенный формат URL для идентификации сообщения. Мы можем создать файл с именем [slug]/page.tsx и поместить в него следующее содержимое:
import { allPosts } from 'contentlayer/generated'; export async function generateStaticParams() { return allPosts.map((post) => ({ slug: post.url, })); } export async function generateMetadata({ params }) { const post = allPosts.find((post) => post.url === params.slug); return { title: post.title, description: post.description, openGraph: { title: post.title, description: post.description, siteName: 'Blog Website', locale: 'en-US', type: 'article', }, twitter: { title: post.title, description: post.description, }, }; } export default async function Blog({ params }) { const post = allPosts.find((post) => post.url === params.slug); return ( <article> <header> <h1>{post.title}</h1> <time>{post.date}</time> </header> <section dangerouslySetInnerHTML={{ __html: post.body.html }} /> </article> ); }
- Функция
generateStaticParams()
создает новый объект из allPosts только с одним свойством, slug, и присваивает его post.url. Затем этот объект используется для получения запрошенного сообщения в блоге. - Функция
generateMetadata()
генерирует метаданные для сообщения в блоге, такие как заголовок, описание и теги социальных сетей. - Компонент
Blog
отображает заголовок, дату и текст сообщения.
Итак, вы успешно создали приложение для блога. Вы можете создать свой собственный пользовательский интерфейс и начать писать свои собственные сообщения в блоге. Продолжайте учиться и делиться своими знаниями с другими