How to setup Contentlayer in your Next.js app?

Robin Singh / January 20th, 2022

3 min read––– views

Table of contents

What is Contentlayer?

Note: Contentlayer still in development and some APIs might change!

Contentlayer turns your content into data - making it super easy to import MD(X) and CMS content in your app.

Setting up Contentlayer

Install Contentlayer in your Next.js app

npm install contentlayer next-contentlayer

Add your Contentlayer config

Create contentlayer.config.js file in the root of the project with the following code.

contentlayer.config.js
import { defineDocumentType, makeSource } from "contentlayer/source-files";

const computedFields = {
  slug: {
    type: "string",
    resolve: (doc) => doc._raw.sourceFileName.replace(/\.md$/, ""),
  },
};

const Post = defineDocumentType(() => ({
  name: "Post",
  filePathPattern: `**/*.md`,
  fields: {
    title: { type: "string", required: true },
    date: { type: "string", required: true },
  },
  computedFields,
}));

export default makeSource({
  contentDirPath: "posts",
  documentTypes: [Post],
});

Set up Next.js plugin in next.config.js (optional: enables live-reload and build setup)

next.config.js
const { withContentlayer } = require("next-contentlayer");

module.exports = withContentlayer()({
  // Your Next.js config...
});

Add some posts

  1. Add posts folder in the root of your app(Where your content will live).
  2. Add .md files(e.g. pre-rendering.md).
  3. Add your content(You can write anything you want, This is just an example).
posts/pre-rendering.md
---
title: "Two Forms of Pre-rendering"
date: "2020-01-01"
---

Next.js has two forms of pre-rendering: **Static Generation** and **Server-side Rendering**. The difference is in **when** it generates the HTML for a page.

- **Static Generation** is the pre-rendering method that generates the HTML at **build time**. The pre-rendered HTML is then _reused_ on each request.
- **Server-side Rendering** is the pre-rendering method that generates the HTML on **each request**.

Importantly, Next.js lets you **choose** which pre-rendering form to use for each page. You can create a "hybrid" Next.js app by using Static Generation for most pages and using Server-side Rendering for others.

Fetch and display your posts

pages/index.js
import Link from "next/link";
import { allPosts } from ".contentlayer/data";
import { pick } from "@contentlayer/client";

export default function Home({ posts }) {
  return (
    <section>
      <ul>
        {posts.map(({ slug, date, title }) => (
          <li key={slug}>
            <Link href={`/posts/${slug}`}>
              <a>{title}</a>
            </Link>
            <br />
            <small>{date}</small>
          </li>
        ))}
      </ul>
    </section>
  );
}

// Statically fetch all posts
export async function getStaticProps() {
  const posts = allPosts.map((post) => pick(post, ["title", "date", "slug"]));

  return { props: { posts } };
}

Create dynamic routes for each post

In this section you should know how dynamic routes works in Next.js,

Add posts/[slug].js inside pages folder.

pages/posts/[slug].js
import { allPosts } from '.contentlayer/data'

export default function Post({ post }) {
  return (
    <article>
      <h1>{post.title}</h1>
      <div>{post.date}</div>

      <div dangerouslySetInnerHTML={{ __html: post.body.html }} />
    </article>
  )
}

export async function getStaticPaths() {
  return {
    paths: allPosts.map((p) => ({ params: { slug: p.slug } })),
    fallback: false,
  }
}

// Statically fetch post by slug
export async function getStaticProps({ params }) {
  const post = allPosts.find((post) => post.slug === params?.slug)

  return { props: { post } }
}

Now we are done 🎉, Check http://localhost:3000 to see the results!

Conclusion

In this guide, We learned about how we can integrate Next.js with Contentlayer, As well as how we can display all posts and post by slug.

An online demo of the application that we built is hosted on Vercel and the code is available on GitHub.

Make sure to contact me if you have any questions.

Was this helpful?

Never miss anything

Get emails from us about event, blog, newsletter, marketing, tech, and early access to new articles.