Build a blog app with new Next.js 13 app folder and Contentlayer

Contents

Create a Next.js app
Create a blog page with contentlayer

Styling the blog
Custom components
Highlight codes

Lets get started

First, we need to create a new Next.js app with the new app folder feature:

npx create-n…


This content originally appeared on DEV Community and was authored by Arshad Yaseen

Contents

  • Create a Next.js app
  • Create a blog page with contentlayer
  • Styling the blog
  • Custom components
  • Highlight codes

Lets get started

First, we need to create a new Next.js app with the new app folder feature:

npx create-next-app@latest --ts

You can also use Javascript instead of Typescript. In this tutorial we will use Typescript.

Then, you need to install the Contentlayer:

npm i contentlayer next-contentlayer @opentelemetry/api

Now, export the contentlayer config in the next.config.js:

const { withContentlayer } = require('next-contentlayer')

module.exports = withContentlayer({
  experimental: { appDir: true },
})

Now, we need to create a contentlayer.config.ts file in the root of the project:

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


const Post = defineDocumentType(() => ({
  name: "Post",
  filePathPattern: `**/*.mdx`,
  contentType: "mdx",
  fields: {
    title: {
      type: "string",
      description: "The title of the post",
      required: true,
    },
    description: {
      type: "string",
      description: "The description of the post",
      required: true,
    },
  },
  computedFields: {
    url: {
      type: "string",
      resolve: (doc) => `/posts/${doc._raw.flattenedPath}`,
    },
  },
}));

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

Above code is the config for the Contentlayer. It will create a Post document type and will generate the url field based on the flattenedPath field.

Now, we need to create a posts folder in the root of the project and create a hello-world.mdx file in it:

---
title: "How to create Next.js app"
description: "Learn how to create Next.js app"
---

# Install Next.js

### Fist you need to install Next.js with the following command:

npm i create-next-app@latest

Then, restart the app with the following command:

npm run dev

Now, you can see new .contentlayer folder in the root of the project. This folder contains the generated JSON files, types and more.

generate contentlayer folder

Now, we need to create a posts folder in the app folder and create a [slug] folder in it. and create a page.tsx file in [slug] folder:

app/posts/[slug]/page.tsx

import { allPosts } from "contentlayer/generated";
import { getMDXComponent } from "next-contentlayer/hooks";

export const generateStaticParams = async () =>


  allPosts.map((post) => ({ slug: post._raw.flattenedPath }));
  export const generateMetadata = ({ params }:any) => {
    const post = allPosts.find((post:any) => post._raw.flattenedPath === params.slug)
    return { title: post?.title,description: post?.description }
  }

const PostLayout = ({ params }: { params: { slug: string } }) => {
  const post = allPosts.find(
    (post) => post._raw.flattenedPath === params.slug
  );

  let MDXContent;

  if (!post) {
    return <div>404</div>;
  } else {
    MDXContent = getMDXComponent(post!.body.code);
  }

  return (
    <div>
      <h1>
        {post.title}
      </h1>
      <p>{post.description}</p>
      <article>
        <MDXContent />
      </article>
    </div>
  );
};

export default PostLayout;

Above code is the page for the blog post. It will render the blog post based on the slug parameter.

Now, you can see the blog rendered in the http://localhost:3000/posts/hello-world:

blog rendered

Styling the blog

Now, we need to style the blog using CSS or others. In this tutorial, we will use CSS:

globals.css

pre {
  padding: 15px 20px;
  border-radius: 10px;
  background-color: #f9f8f981;
  overflow: auto;
  font-size: 0.9rem;
  margin: 40px 0;
}
article p {
  font-size: 1rem;
  line-height: 1.8rem;
  margin-top: 20px;
}
article h1 {
  font-size: 2.5rem;
  line-height: 3.5rem;
  margin-top: 60px;
  font-weight: 425;
}

...

Now, you can see the blog styled:

styled blog

Also you can use TailwindCSS or others.

Custom components

Custom components is a great feature of MDX. You can create your own components and use them in your blog posts.

For example, we can create a CodeSnippet component:

app/posts/[slug]/page.tsx

import { allWritings } from "contentlayer/generated";
import { getMDXComponent } from "next-contentlayer/hooks";
import { Snippet } from "@geist-ui/core";

...

const CodeSnippet = (props: any) => (
 <Snippet {...props} text={props.text} />
);

 return (
    <div>
      <h1>
        {writing.title}
      </h1>
      <p>{writing.description}</p>
      <article>
        <MDXContent components={{ CodeSnippet }} />
      </article>
    </div>
  );

export default PostLayout;

Now, you can use the CodeSnippet component in your blog posts:

---
title: How to create a Next.js app
description: Learn how to create a Next.js app
---

# Install Next.js

### First, install Next.js using the following command:

<CodeSnippet text="npx create-next-app@latest" />

Now, you can see the CodeSnippet component in the blog post:

code snippet

List all posts

Now, we need to create a page that lists all posts. For this, we need to create a posts folder in the app folder and create a page.tsx file in it:

app/posts/page.tsx

import Link from 'next/link'
import { allPosts, Post } from 'contentlayer/generated'

function PostCard(post: Post) {
  return (
    <div>
      <h2>
        <Link href={post.url} legacyBehavior>
          {post.title}
        </Link>
      </h2>
      <p>{post.description}</p>
    </div>
  )
}

function page() {
  const posts = allPosts

  return (
    <div>
      <div>
      {posts.map((post, idx) => (
        <PostCard key={idx} {...post} />
      ))}
      </div>
    </div>
  )
}

export default page;

Now, you can see the list of all posts in the http://localhost:3000/posts:

list of all posts

Highlight codes

Now, we need to highlight the codes in the blog posts. For this, we will use rehype-pretty-code:

npm i rehype-pretty-code shiki

Now, we need to add the rehype-pretty-code plugin to the contentlayer.config.ts file:

contentlayer.config.ts

import { defineDocumentType, makeSource } from "contentlayer/source-files";
import rehypePrettyCode from "rehype-pretty-code";

const Writing = defineDocumentType(() => ({
  ...
}));

const rehypeoptions = {
    // Use one of Shiki's packaged themes
    theme: "light-plus",
    keepBackground: isDark ,
    onVisitLine(node: any) {
      if (node.children.length === 0) {
        node.children = [{ type: "text", value: " " }];
      }
    },
    onVisitHighlightedLine(node: any) {
      node.properties.className.push("highlighted");
    },
    onVisitHighlightedWord(node: any, id: any) {
      node.properties.className = ["word"];
    },
  };

export default makeSource({
  contentDirPath: "writings",
  documentTypes: [Writing],
  mdx: {
    rehypePlugins: [[rehypePrettyCode, rehypeoptions]],
  },
});

Now, you can see the highlighted codes in the blog posts:

highlighted codes

You can find more information about rehype-pretty-code
and Shiki themes.

Conclusion

In this tutorial, we have learned how to create a blog using Next.js, Contentlayer, and MDX. We have learned how to create a blog post, how to list all posts, and how to highlight codes in the blog posts.

You can find the source code of the Contentlayer blog in the following GitHub repository:

Source code of example

Resources

About the author

Arshad Yaseen. I'm a software engineer and I love to create aesthetic frontends. If you have any questions, feel free to ask me on Twitter.


This content originally appeared on DEV Community and was authored by Arshad Yaseen


Print Share Comment Cite Upload Translate Updates
APA

Arshad Yaseen | Sciencx (2023-04-05T18:46:15+00:00) Build a blog app with new Next.js 13 app folder and Contentlayer. Retrieved from https://www.scien.cx/2023/04/05/build-a-blog-app-with-new-next-js-13-app-folder-and-contentlayer/

MLA
" » Build a blog app with new Next.js 13 app folder and Contentlayer." Arshad Yaseen | Sciencx - Wednesday April 5, 2023, https://www.scien.cx/2023/04/05/build-a-blog-app-with-new-next-js-13-app-folder-and-contentlayer/
HARVARD
Arshad Yaseen | Sciencx Wednesday April 5, 2023 » Build a blog app with new Next.js 13 app folder and Contentlayer., viewed ,<https://www.scien.cx/2023/04/05/build-a-blog-app-with-new-next-js-13-app-folder-and-contentlayer/>
VANCOUVER
Arshad Yaseen | Sciencx - » Build a blog app with new Next.js 13 app folder and Contentlayer. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2023/04/05/build-a-blog-app-with-new-next-js-13-app-folder-and-contentlayer/
CHICAGO
" » Build a blog app with new Next.js 13 app folder and Contentlayer." Arshad Yaseen | Sciencx - Accessed . https://www.scien.cx/2023/04/05/build-a-blog-app-with-new-next-js-13-app-folder-and-contentlayer/
IEEE
" » Build a blog app with new Next.js 13 app folder and Contentlayer." Arshad Yaseen | Sciencx [Online]. Available: https://www.scien.cx/2023/04/05/build-a-blog-app-with-new-next-js-13-app-folder-and-contentlayer/. [Accessed: ]
rf:citation
» Build a blog app with new Next.js 13 app folder and Contentlayer | Arshad Yaseen | Sciencx | https://www.scien.cx/2023/04/05/build-a-blog-app-with-new-next-js-13-app-folder-and-contentlayer/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.