Implementing Homepage Functionality, Adding Contentlayer Post List - Modern Next.js Blog Series #06

Published on

This article is also published at it Help 2022 iThome Ironman Contest

Let's use Contentlayer installed in the previous article to implement the homepage post list functionality, displaying all Markdown articles.

Result screenshot as follows:

Index Page Result

The code changes for this article are as follows: https://github.com/Kamigami55/nextjs-tailwind-contentlayer-blog-starter/compare/day05-markdown-contentlayer...day06-index-page-bare-bone


Sorting Articles, Using date-fns

In the last article, we set the path for articles in contentlayer.config.ts. Contentlayer will read content/posts/**/*.md, which are all .md files in content/posts/, becoming the allPosts array for our use.

However, Contentlayer does not guarantee the order of articles, and I wish the homepage post list to be sorted from newest to oldest. Therefore, we need to sort the article array ourselves.

We will use date-fns to sort based on the date attribute of the articles.

Installing date-fns

pnpm add date-fns

Modifying contentLayerAdapter.js

Import the compareDesc function from date-fns to sort allPosts, and export it as the allPostsNewToOld constant for later use in the homepage post list:

import { allPosts, Post } from 'contentlayer/generated'; import { defineDocumentType, defineNestedType, makeSource, } from 'contentlayer/source-files'; import { compareDesc } from 'date-fns'; # Add this export { allPosts, defineDocumentType, defineNestedType, makeSource, Post }; # Add the following export const allPostsNewToOld = allPosts?.sort((a, b) => { return compareDesc(new Date(a.date), new Date(b.date)); }) || [];

Adding the Post List to the Homepage

Modify /src/pages/index.tsx:

import type { NextPage } from "next"; import Head from "next/head"; import Image from "next/image"; import { allPostsNewToOld, Post } from "@/lib/contentLayerAdapter"; import styles from "@/styles/Home.module.css"; export function getStaticProps() { const posts = allPostsNewToOld; return { props: { posts } }; } type Props = { posts: Post[]; }; const Home: NextPage<Props> = ({ posts }) => { return ( <div className={styles.container}> <Head> <title>Create Next App</title> <meta name="description" content="Generated by create next app" /> <link rel="icon" href="/favicon.ico" /> </Head> <main className={styles.main}> <h1 className={styles.title}> Welcome to <a href="https://nextjs.org">Next.js!</a> </h1> <p className={styles.description}> Get started by editing{" "} <code className={styles.code}>pages/index.tsx</code> </p> <div className={styles.grid}> {posts.map((post) => ( <a key={post.slug} href={post.path} className={styles.card}> <h2>{post.title}</h2> <p>{post.description}</p> </a> ))} </div> </main> <footer className={styles.footer}> <a href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app" target="_blank" rel="noopener noreferrer" > Powered by{" "} <span className={styles.logo}> <Image src="/vercel.svg" alt="Vercel Logo" width={72} height={16} /> </span> </a> </footer> </div> ); }; export default Home;

Result

Done! Use pnpm dev and browse the homepage, and you should see two articles displayed on the homepage, screenshot as follows:

Index Page Result

Summary & Next Article

Congratulations on successfully importing Markdown articles processed by Contentlayer and displaying them on the homepage post list!

The code changes for this article are as follows: https://github.com/Kamigami55/nextjs-tailwind-contentlayer-blog-starter/compare/day05-markdown-contentlayer...day06-index-page-bare-bone

But if you click on these two articles, you will see a 404 error screen, because we have not yet implemented the article detail page.

In the next article, let's implement the article detail page and display the full article content!