contentlayer 参考使用
当前contentlayer 主要支持next,以下是使用next 的试用
创建项目
- 创建next 项目
npx create-next-app contentlayer-demo
- 安装contentlayer
cd contentlayer-demo
yarn add contentlayer next-contentlayer date-fns
- 项目配置
包含了next 以及ts
next 配置 next.config.js
/** @type {import('next').NextConfig} */
const { withContentlayer } = require('next-contentlayer')
module.exports = withContentlayer({
reactStrictMode: true,
})
contentlayer.config.js
import { defineDocumentType, makeSource } from 'contentlayer/source-files'
export const Post = defineDocumentType(() => ({
name: 'Post',
filePathPattern: `**/*.md`,
fields: {
title: {
type: 'string',
description: 'The title of the post',
required: true,
},
date: {
type: 'date',
description: 'The date of the post',
required: true,
},
},
computedFields: {
url: {
type: 'string',
resolve: (post) => `/posts/${post._raw.flattenedPath}`,
},
},
}))
export default makeSource({
contentDirPath: 'posts',
documentTypes: [Post],
})
- 创建md文件
参考结构
post 路由定义
[slug].js
import Head from 'next/head'
import Link from 'next/link'
import { format, parseISO } from 'date-fns'
import { allPosts } from '../../.contentlayer/generated'
export async function getStaticPaths() {
const paths = allPosts.map((post) => post.url)
return {
paths,
fallback: false,
}
}
export async function getStaticProps({ params }) {
const post = allPosts.find((post) => post._raw.flattenedPath === params.slug)
return {
props: {
post,
},
}
}
const PostLayout = ({ post }) => {
return (
<>
<Head>
<title>{post.title}</title>
</Head>
<article className="mx-auto max-w-2xl py-16">
<div className="mb-6 text-center">
<Link href="/">
<a className="text-center text-sm font-bold uppercase text-blue-700">Home</a>
</Link>
</div>
<div className="mb-6 text-center">
<h1 className="mb-1 text-3xl font-bold">{post.title}</h1>
<time dateTime={post.date} className="text-sm text-slate-600">
{format(parseISO(post.date), 'LLLL d, yyyy')}
</time>
</div>
<div className="cl-post-body" dangerouslySetInnerHTML={{ __html: post.body.html }} />
</article>
</>
)
}
export default PostLayout
index.js 定义
import Head from 'next/head'
import Link from "next/link"
import Image from 'next/image'
import styles from '../styles/Home.module.css'
import { compareDesc, format, parseISO } from 'date-fns'
import { allPosts } from '../.contentlayer/generated'
export async function getStaticProps() {
const posts = allPosts.sort((a, b) => {
return compareDesc(new Date(a.date), new Date(b.date))
})
return { props: { posts } }
}
function PostCard(post) {
return (
<div className="mb-6">
<time dateTime={post.date} className="block text-sm text-slate-600">
{format(parseISO(post.date), 'LLLL d, yyyy')}
</time>
<h2 className="text-lg">
<Link href={post.url}>
<a className="text-blue-700 hover:text-blue-900">{post.title}</a>
</Link>
</h2>
</div>
)
}
export default function Home({ posts }) {
return (
<div className="mx-auto max-w-2xl py-16 text-center">
<Head>
<title>Contentlayer Blog Example</title>
</Head>
<h1 className="mb-8 text-3xl font-bold">Contentlayer Blog Example</h1>
{posts.map((post, idx) => (
<PostCard key={idx} {
))}
</div>
)
}
启动&效果
- 启动
yarn dev
- 效果
说明
官方文档的一些内容与实际是有差异的,但是通过此可以整体的体验下contentlayer的优势