How to Create A Blog with Next.js + MDX + Chakra UI

February 26, 20213 min read

Today I will talked about the thing that I learned when I setup and create new personal blog with Next.js + MDX and Chakra UI, I spend my weekend (2 days) to created this.

The projects that inspired me a lot, I learn from the code following:

Chakra UI#

I used Chakra UI, then I can customize my React application, custom style and theming, its similar to Theme UI that's I created with Gatsby on another blog.

firstly, install Chakra UI

npm i @chakra-ui/react @emotion/react @emotion/styled framer-motion

Setup ChakraProvider at the root of project, so on Next.js application open pages/_app.js

import { ChakraProvider } from '@chakra-ui/react';
export default function App({ Component, pageProps }) {
return (
<ChakraProvider resetCSS theme={customTheme}>
<Component {...pageProps} />
</ChakraProvider>
);
}

You can read more about Getting started with Chakra UI

MDX#

For this blog, I plan to use .mdx extension instead of .md then I use

  • gray-matter - To use frontmatter format in Markdown.
  • next-mdx-remote - I used this one instead of @next/mdx
import matter from 'gray-matter';
import renderToString from 'next-mdx-remote/render-to-string'
// Assume that `source`` is your markdown content that load from `fs.readFile()`
const { data, content } = matter(source);
const mdxSource = await renderToString(content, {
components: MDXComponents,
mdxOptions: {
remarkPlugins: [
require('remark-slug'),
require('remark-autolink-headings'),
require('remark-emoji'),
require('remark-images')
],
rehypePlugins: []
}
});

and MDXComponents is the custom component that use inside .mdx file, for example

  • I custom <Image /> will use @next/image
  • and > in markdown will render as <Alert> from Chakra UI.
import Image from 'next/image';
const MDXComponents = {
Image,
blockquote: (props) => (
<Alert
mt="4"
role="none"
status="info"
variant="left-accent"
as="blockquote"
rounded="4px"
my="1.5rem"
{...props}
/>
)
};
export default MDXComponents;

for Syntax Highlighter I used prism-react-renderer

Chakra theme#

I want to custom theme, to switch between system or light or dark mode, Fortunately Chakra UI provided us the very easy to implemented.

I added ColorModeScript to pages/_document.js and can custom more theming.

// theme.js
// 1. import `extendTheme` function
import { extendTheme } from "@chakra-ui/react"
// 2. Add your color mode config
const config = {
initialColorMode: "light",
useSystemColorMode: false,
}
// 3. extend the theme
const theme = extendTheme({ config })
export default theme

and this:

// pages/_document.js
import { ColorModeScript } from "@chakra-ui/react"
import NextDocument, { Html, Head, Main, NextScript } from "next/document"
import theme from "./theme"
export default class Document extends NextDocument {
render() {
return (
<Html lang="en">
<Head />
<body>
<ColorModeScript initialColorMode={theme.config.initialColorMode} />
<Main />
<NextScript />
</body>
</Html>
)
}
}

Writing#

time to blogging, I create a file inside data/posts with frontmatter

---
title: 'How to Create A Blog with Next.js + MDX + Chakra UI'
publishedAt: '2021-02-26'
---
Content go here.

the final step, jsut deploy with Vercel Link to github repository and follow the instruction step, and my personal blog is live now.

Made in 🇹🇭 By Chai Phonbopit