avatarKJ

Summary

The web content provides a comprehensive tutorial on building a food blog using Next.js, MDX, Tailwind CSS, and TypeScript.

Abstract

This tutorial guides readers through the process of creating a food recipes blog by leveraging the power of Next.js for server-side rendering, MDX for integrating JSX with Markdown, Tailwind CSS for utility-first styling, and TypeScript for type safety. It covers setting up a Next.js app, installing necessary dependencies, converting JavaScript to TypeScript, configuring Tailwind CSS, creating a post list page, and developing individual post content pages with dynamic routing. The tutorial emphasizes the benefits of using MDX for content management, allowing for reusable components and easy updates to recurring sections like ingredients and directions. It also showcases how to utilize Next.js' Image component for optimized thumbnails and provides sample code snippets and components for a complete blog implementation. The author encourages readers to use the provided GitHub repository for reference and suggests trying out a cost-effective AI service for similar performance to ChatGPT Plus.

Opinions

  • The author believes that using Markdown with MDX is a practical approach for writing blog posts, especially when dealing with reusable text.
  • MDX is praised for its flexibility in creating and updating articles, as it allows the inclusion of JSX in Markdown files.
  • Tailwind CSS is recommended for its ability to remove unused styles in production and for providing a set of typography classes.
  • The use of TypeScript is advocated for its strict type checking, which enhances code reliability.
  • The tutorial suggests that separating components, such as headers, meta information, and thumbnails, simplifies code management and improves maintainability.
  • The author expresses confidence in the Next.js framework for its dynamic routing capabilities, which are essential for creating content-rich blogs.
  • The author promotes the use of an AI service, ZAI.chat, as a cost-effective alternative to ChatGPT Plus, implying its value for money and comparable functionality.

Build a Food Blog with Next.js, MDX, Tailwind CSS, and TypeScript

I think it’s a good idea to write a blog post using Markdown. But if you have text to reuse, it doesn’t make sense to copy and paste it into an article every time. If you want to modify that text, you will have to modify all markdown files. MDX allows you to write JSX in your markdown files, making it easy and flexible to create and update articles.

In this tutorial, we’ll build a food recipes blog with Next.js, MDX, Tailwind CSS, and TypeScript. Food blogs use headlines such as “Ingredients” and “Directions” in every article, so it makes sense to use MDX.

Create a Next.js App

Create a new Next.js app using create-next-app, which is named "my-food-blog" in this tutorial:

yarn create next-app my-food-blog

Then, start your dev server by running the following command:

cd my-food-blog
yarn dev

Open http://localhost:3000 from your browser. You should see a page that says “Welcome to Next.js!”.

Install Dependencies

For MDX:

yarn add next-mdx-remote gray-matter

For Tailwind CSS:

yarn add tailwindcss postcss autoprefixer @tailwindcss/typography

For TypeScript:

yarn add --dev typescript @types/react @types/react-dom @types/node

Convert Existing JavaScript to TypeScript

Rename the two .js files to .tsx files:

  1. pages/_app.js -> _app.tsx
  2. pages/index.js -> index.tsx

We won’t use the api/hello.js file, so you can delete it.

Creating TSConfig

Running yarn dev again will generate the next-env.d.ts and tsconfig.json files in your project root.

Open the tsconfig.json file and turn on strict mode:

{
  "compilerOptions": {
    ...
    "strict": true,
    ...
  },
  ...
}

This will enable strict type checking.

Setting Up Tailwind CSS

Create Config Files

The following command will generate the tailwind.config.js and postcss.config.js files:

yarn tailwindcss init -p

Configure Tailwind

Open the tailwind.config.js file and configure it as follows:

Configuring the purge option will automatically remove unused styles from CSS in production.

Adding the @tailwindcss/typography plugin allows you to use a set of prose classes.

Include Tailwind

Open pages/_app.tsx and import Tailwind directly in it:

In addition, add the built-in type AppProps as above while we are here.

Now that the basic configuration and setup are complete, let’s create the contents.

Create a Post List Page

Open pages/index.tsx and rewrite all the code in it as follows:

Use getStaticProps to fetch a list of posts at build time.

This page requires several files, so let’s create them one by one.

mdxUtils

Create utils/mdxUtils.ts in your project root:

This utility file is based on that of blog-starter-typescript and I modified it for MDX.

Each MDX file in the _posts directory (which we will create later) is read and gray-matter returns an object containing its front matter and content.

constants

Create utils/constants.ts:

IPost

Create types/post.ts in your project root and declare the post object structure using the interface as follows:

Layout Component

Let’s create a Layout component that will be shared across all pages.

Create components/Layout.tsx in your project root:

Header Component

Create components/Header.tsx:

Separating each part as a component makes it easier to manage.

Meta Component

Create components/Meta.tsx:

For tags that have different content on each page and need to be overwritten, such as description and og: image, you can use the key property to avoid duplicate tags.

Thumbnail Component

Next.js has a built-in Image Component and Automatic Image Optimization since version 10.

Create components/Thumbnail.tsx:

You can download and use the static files in my repo for testing.

Create MDX Documents

You can use the sample files in my repo for testing.

Create a directory called _posts in your project root and add files to it.

Now, start the dev server and see the result on your browser:

We haven’t created a content page yet, so clicking on any recipe link should bring up a 404 page. Now let’s create it.

Create a Post Content Page

In Next.js, you can create dynamic routes by using square brackets.

Create pages/posts/[slug].tsx:

This page uses the serialize function and the MDXRemote component provided by next-mdx-remote. serialize is used in getStaticProps because it is intended to be executed on the server side. On the other hand, <MDXRemote /> is intended to be executed on the client side. The MDX contents are loaded using these two.

If your dynamic route has getStaticProps, you need to add getStaticPaths to define a list of paths.

The optional parameters in the second argument of serialize can be easily understood by looking at the MDX files. Open _posts/how-to-make-stock-from-kelp-and-bonito-flakes.mdx:

By specifying the scope parameter of serialize, the values of the front matter can be passed to each component as props.

If you have additional information, just write it anywhere you like with Markdown syntax.

Now let’s create the components used in the MDX files.

Ingredients Component

Create components/Ingredients.tsx:

Directions Component

Create components/Directions.tsx:

Tips Component

Create components/Tips.tsx:

Now go to your browser and click on the recipe links. The content of each page should have been displayed perfectly.

🎉🎉🎉

Conclusion

In this tutorial, we created a simple blog with Next.js and MDX. Next time, I’ll write about how to add dark mode to this blog, so stay tuned.

The source code for this tutorial can be found on GitHub.

Nextjs
Mdx
Tailwind Css
Typescript
Tutorial
Recommended from ReadMedium