
In part, before we have completed making a home page with a few components, the home page will show a blog. but it's still statically here we will use gatsby-plugin-mdx
to convert markdown into pages.
- Build Blog Site using Gatsby JS — Part 1 (Getting Started)
- Build Blog Site using Gatsby JS — Part 2 (Chakra UI & Home Page)
- Build Blog Site using Gatsby JS — Part 3 (Gatsby Plugin Mdx)
- Build Blog Site using Gatsby JS — Part 4 (React Helmet and SEO tag)
- Build Blog Site using Gatsby JS — Part 5 (Deploy site to Netlify)
Here are the steps Gatsby follows for making this happen.
- Read files into Gatsby from the filesystem
- Transform Markdown to HTML and frontmatter to data
- Add a Markdown file
- Create a Collection Route component for the Markdown files
Installation
npm install gatsby-plugin-mdx @mdx-js/mdx @mdx-js/react gatsby-source-filesystem
Configure Plugin
Gatsby Source Filesystem
add following code inside plugins
on gatsby-config.js
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'blogs',
path: `${__dirname}/src/blogs`
}
}
Gatsby Plugin Mdx
You’ll use the plugin gatsby-plugin-mdx
to recognize files that are Markdown and read their content. The plugin will convert the frontmatter
metadata part of your Markdown files frontmatter and the content part as HTML.
// gatsby-config.js
module.exports = {
....
plugins: [
....
{
resolve: `gatsby-plugin-mdx`,
options: {
extensions: ['.mdx', '.md']
}
},
],
};
Add Markdown File
Create /src/blogs directory and create a file name first-post.md
Frontmatter Metadata
When you create a Markdown file, you can include a set of key/value pairs that can be used to provide additional data relevant to specific pages in the GraphQL data layer. This data is called “frontmatter” and is denoted by the triple dashes at the start and end of the block. This block will be parsed by gatsby-transformer-remark
YAML. You can then query the data through the GraphQL API from your React components.
// /src/bogs/first-post.md
---
date: "2022-02-15"
title: "My first blog post"
---
## Introduction
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Create a Collection Route for the Markdown files
Create /src/pages/{mdx.slug}.jsx
file.
import React from 'react';
import { graphql } from 'gatsby';
import Layout from '../components/Layout';
import { Box, Heading, Text, Image, Flex } from '@chakra-ui/react';
import { MDXProvider } from '@mdx-js/react';
import { MDXRenderer } from 'gatsby-plugin-mdx';
const chakraUiComponents = {
h1: (props) => <Heading as="h1" paddingY="5" size="2xl" {...props} />,
h2: (props) => <Heading as="h2" paddingY="5" size="xl" {...props} />,
h3: (props) => <Heading as="h3" paddingY="5" size="lg" {...props} />,
h4: (props) => <Heading as="h4" paddingY="5" size="md" {...props} />,
h5: (props) => <Heading as="h5" paddingY="5" size="sm" {...props} />,
h6: (props) => <Heading as="h6" paddingY="5" size="xl" {...props} />,
p: (props) => <Text lineHeight={2} paddingBottom="4" fontSize="lg" {...props} />,
img: (props) => <Image marginBottom="4" {...props} />
};
export default function MarkdownPages({ data }) {
const { slug, frontmatter, body, timeToRead } = data.mdx;
return (
<Layout>
<Heading as="h1" size="3xl" paddingBottom="5">{frontmatter.title}</Heading>
<Flex justifyContent={"space-between"}>
<p>{timeToRead} min</p>
<p>{frontmatter.date}</p>
</Flex>
{frontmatter.cover &&
<Box paddingY="2">
<Image src={frontmatter.cover} />
</Box>
}
<Box paddingY="8">
<MDXProvider
components={chakraUiComponents}
>
<MDXRenderer>
{body}
</MDXRenderer>
</MDXProvider>
</Box>
</Layout>
);
}
export const pageQuery = graphql`
query($id: String!) {
mdx(id: { eq: $id }) {
body
slug
timeToRead
frontmatter {
date(formatString: "MMMM DD, YYYY")
title
cover
}
}
}
`;
The filename is {mdx.slug}
that mean to tell gatsby if search query is from GraphQL query, see the bold text below
query($id: String!) {
mdx(id: { eq: $id }) {
body
slug
timeToRead
frontmatter {
date(formatString: "MMMM DD, YYYY")
title
cover
}
}
}
Gatsby will find the markdown files that registered before, if match with the slug then render the page.
If you not knowing about graphql in Gatsby JS, you can visit page at http://localhost:8000/__graphiql and you can write a query to show all markdown data
Basically Gatsby provide GrapQL server and client tool, with that we can consume the data like markdown, images, and other by function graphql , and the result is data json format.
Back to the main topic
Cause we use Chakra UI that all is based on component so we use <MdxProvider />
and set custom component like h1-h6, image, paragraph on components properties.
const chakraUiComponents = {
h1: (props) => <Heading as="h1" paddingY="5" size="2xl" {...props} />,
h2: (props) => <Heading as="h2" paddingY="5" size="xl" {...props} />,
h3: (props) => <Heading as="h3" paddingY="5" size="lg" {...props} />,
h4: (props) => <Heading as="h4" paddingY="5" size="md" {...props} />,
h5: (props) => <Heading as="h5" paddingY="5" size="sm" {...props} />,
h6: (props) => <Heading as="h6" paddingY="5" size="xl" {...props} />,
p: (props) => <Text lineHeight={2} paddingBottom="4" fontSize="lg" {...props} />,
img: (p
Inside of <MdxProvider>
there is <MdxRenderer>
which is will convert a meta data from markdown into JSX pages.
Open on your browser and go to http://localhost:8000/first-post
Show list of blog on Homepage
we has been created page for blog detail, we’ll add a blog list into homepage
on the /src/pages/index.jsx
we will add GraphQL query to select markdown file that we created before.
update the code
import { graphql } from "gatsby";
export default function index({ data }) {
const { blogs } = data.allMdx;
return (
<Layout>
<Text fontWeight={"black"}>Latest Article</Text>
{blogs.map((blog) => (
<Blog
link={blog.slug}
title={blog.frontmatter.title}
date={blog.frontmatter.date}
excerpt={blog.excerpt}
/>
))}
</Layout>
);
}
export const query = graphql`
query BlogList {
allMdx {
blogs: nodes {
excerpt
frontmatter {
title
date(formatString: "MMM DD, YYYY")
}
slug
timeToRead
}
}
}
`;
Open on your browser and go to homepage, it will shown all list of markdown blog that you created 👌.