I decided to start a blog and keep a record of my development adventures.
I'm a to the point kind of guy so let's get to it:
Adding Mdx
Why MDX, you may ask? Markdown is great, but sometimes you need more expressiveness yet, especially for a development blog and if you want to do unique things. With MDX, you can write pure Markdown or go crazy and add React components everywhere (which I'm planning to do ๐)
yarn add gatsby-plugin-mdx @mdx-js/mdx @mdx-js/react
or
npm i --save gatsby-plugin-mdx @mdx-js/mdx @mdx-js/react
You can now add the gatsby-plugin-mdx
plugin to your gatsby-config.js
:
plugins: [
`gatsby-plugin-mdx`
]
With this done, you can create your first post at src/blog/some-post-slug.mdx
, and if you navigate to https://localhost:8000/blog/some-post-slug
, you'll see your first post!
But it looks like ๐ฉ๐ฉ๐ฉ
Specifying a layout
The mdx plugin we just added lets you specify layout components for your mdx files. I'll only use mdx for my blog, so setting a default layout will be enough for me, but you can specify different configurations if you need to.
{
resolve: `gatsby-plugin-mdx`,
options: {
defaultLayouts: {
default: require.resolve("./src/components/PostLayout.js"),
},
},
},
Creating the layout
For a simple blog, you need nothing different from standard Gatsby layouts. You'll get the content of the post on the children
property. The only part that needs special consideration is adding a list of the latest blog posts, for which you need three things:
1 - Add this to your gatsby-config.js
:
Setup gatsby-source-filesystem
to create nodes for the src/pages/blog
folder (otherwise, they won't show in the next step):
{
resolve: `gatsby-source-filesystem`,
options: {
name: `posts`,
path: `${__dirname}/src/pages/blog`,
},
},
2 - Getting a list of the latest five posts sorted by date:
const { allMdx } = useStaticQuery(graphql`
query PostLayoutQuery {
allMdx(sort: {fields: frontmatter___date, order: DESC}, limit: 6) {
edges {
node {
frontmatter {
title
date
}
slug
}
}
}
}`)
Yes, because we want to show five posts and we'll always get the current post in the first place of the list, we'll ask for six and filter out the current one:
const posts = allMdx.edges.filter(({ node }) => !location.pathname.includes(node.slug))
3 - Link to the other posts
It could look something like this:
<List>
{posts.map(({ node }) => <Item key={node.slug}>
<Link to={`/blog/${node.slug}`}>
{node.frontmatter.title}
</Link>
</Item>)}
</List>
Wrapping up
This is good enough for the first version of a blog. I'll add custom components to show jsx
better than I'm doing now in another post. We'll use gatsby-node.js
to specify our custom frontmatter fields, create a custom slug URL, so we don't have to hardcode the /blog
path in our links and more.
An example of the complete layout file (because I know you are looking for it)
PostLayout.js
import React from "react"
import { useStaticQuery, graphql, Link } from 'gatsby'
export default function PostLayout({ children }) {
const data = useStaticQuery(graphql`
query PostLayoutQuery {
allMdx(sort: {fields: frontmatter___date, order: DESC}, limit: 6) {
edges {
node {
frontmatter {
title
date
}
slug
}
}
}
}
`)
const posts = allMdx.edges.filter(({ node }) => !location.pathname.includes(node.slug))
return <div>
<main>
{children}
<h3>Latest posts</h3>
<ul>
{posts.map(({ node }) => <li key={node.slug}>
<Link to={`/blog/${node.slug}`}>
{node.frontmatter.title}
</Link>
</li>)}
</ul>
</main>
</div>
}
Top comments (0)