Use Contentlayer with NextJS
Dec 23, 2021——Edit in Github
I don't write a lot (though is something I want to change), but this site is some kind of playground to try new things. The other day stumbled upon a list of personal websites of developers and designers and going through them found some using Contentlayer, it looked interesting, so let's try it!
What is Contentlayer?
Contentlayer turns your content into data - making it super easy to import MD(X) and CMS content in your app.
How to add it to your NextJS site?
The first step is to install the needed libraries:
Once the installation is complete, a
contentlayer.config.ts file needs to be created in the root folder of your project. This is the file where all the content definition and project configuration are done.
In my case I only have one type of content, blog posts coming from MDX files.
defineDocumentType for each type of content type you want Contentlayer to manage. Using the fields property we map frontmatter fields from the document to object properties you can freely use (and to typescript types!).
You see that computedFields property?
This are some kind of virtual fields that can go through and extra process, for example to get the slug from the file name, or to get some extra metadata like reading time.
Finally we complete the configuration using
makeSource. We need to add the content types defined above and we have the option to set extra configuration for MDX files, like using remark and rehype plugins.
With this we are almost done with the configuration, but since we are using NextJS we can hook up to its build process to autogenerate the content and enable live-reload. To do this we need to add some changes on
next.config.js. In my case I'm using next-compose-plugins so it looks like this:
How to use it?
With everything in place, running
yarn dev (or
yarn build for production) will trigger Contentlayer build process, which generates several files inside the
node_modules/.contentlayerfolder which then you can import wherever you want to use them.
For my content I defined a content type called
Post, so for example to look for the single post when a slug is accessed:
And since I'm using MDX we need the
useMDXComponent hook to render the content:
That's it! Our
Post object has access to all the properties we defined as
computedFields plus some extra (like the above
body.code for MDX files).
You can see the complete changeset for this here: https://github.com/osiux/osiux.ws/pull/5/files
Only major issue was that I was using a remark plugin (to embed media content) that is using an old unified version, while Contentlayer uses latest version and it was causing some kind of incompatibility.
The process to implement Contentlayer was pretty straightforward, currently the library lacks some documentation, but given its alpha state it's understandable, and looking at websites already using it made it easier to use.