Gatsby is a static web site framework that’s based on React.
We can use it to create static websites from external data sources and more.
In this article, we’ll look at how to create a site with Gatsby.
Adding Markdown Pages
We can add pages from Markdown by adding the gatsby-transformer-remark
and gatsby-source-filesystem
plugins.
To do this, we write:
gatsby-config.js
module.exports = {
plugins: [
`gatsby-transformer-remark`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: `content`,
path: `${__dirname}/src/content`,
},
},
],
}
gatsby-node.js
exports.createPages = async ({ actions, graphql, reporter }) => {
const { createPage } = actions
const blogPostTemplate = require.resolve(`./src/templates/post.js`)
const result = await graphql(`
{
allMarkdownRemark(
sort: { order: DESC, fields: [frontmatter___date] }
limit: 1000
) {
edges {
node {
frontmatter {
slug
}
}
}
}
}
`)
if (result.errors) {
reporter.panicOnBuild(`Error while running GraphQL query.`)
return
}
result.data.allMarkdownRemark.edges.forEach(({ node }) => {
createPage({
path: node.frontmatter.slug,
component: blogPostTemplate,
context: {
slug: node.frontmatter.slug,
},
})
})
}
src/templates/post.js
import React from "react" { graphql } from "gatsby"
export default function Template({
data,
}) {
const { markdownRemark } = data
const { frontmatter, html } = markdownRemark
return (
<div className="blog-post-container">
<div className="blog-post">
<h1>{frontmatter.title}</h1>
<h2>{frontmatter.date}</h2>
<div
className="blog-post-content"
dangerouslySetInnerHTML={{ __html: html }}
/>
</div>
</div>
)
}
export const pageQuery = graphql`
query($slug: String!) {
markdownRemark(frontmatter: { slug: { eq: $slug } }) {
html
frontmatter {
date(formatString: "MMMM DD, YYYY")
slug
title
}
}
}
`
src/content/post.md
---
title: My First Post
date: 2019-07-10
slug: /my-first-post
---
This is my first Gatsby post written in Markdown!
We add the gatsby-source-filesystem
plugin to read the Markdown files from the src/content
folder.
And we add the gatsby-transformer-remark
plugin to transform the Markdown files to HTML.
Then in gatsby-node.js
, we get the Markdown content with the allMarkdownRemark
query.
We sort the entries by date
with the sort
values.
And we limit the number of entries to 1000.
And we specify that we return the slug
in the result.
Then we call forEach
to call the createPage
function to create the pages.
The path
is the URL path to access the page.
component
has the template file path.
And context
has the data that we want to display from the result entry.
In post.js
, we have the query to get a single entry.
We get the entry with give slug with the markdownRemark
query.
Then we get the html
field to get the content.
frontmatter
has the metadata for the page.
And we get that from the data
prop’s markdownRemark
property.
Finally, we render that in the JSX of Template
.
Now we should see the post.md
content displayed.
Add a List of Markdown Blog Posts
We can also add a page withn multiple posts.
To do this, we write:
src/page/index.js
import React from "react"
import { graphql } from "gatsby"
import { Link } from "gatsby"
const PostLink = ({ post }) => (
<div>
<Link to={post.frontmatter.slug}>
{post.frontmatter.title} ({post.frontmatter.date})
</Link>
</div>
)
const IndexPage = ({
data: {
allMarkdownRemark: { edges },
},
}) => {
const Posts = edges
.filter(edge => !!edge.node.frontmatter.date)
.map(edge => <PostLink key={edge.node.id} post={edge.node} />)
return <div>{Posts}</div>
}
export default IndexPage
export const pageQuery = graphql`
query {
allMarkdownRemark(sort: { order: DESC, fields: [frontmatter___date] }) {
edges {
node {
id
excerpt(pruneLength: 250)
frontmatter {
date(formatString: "MMMM DD, YYYY")
slug
title
}
}
}
}
}
`
We create the PostLink
component to display a link for the post.
IndexPage
has the posts.
We get the posts data from the data
prop’s allMarkdownRemark.edges
property.
And we map the entries to the PostLink
component to render each entry with the PostLink
component.
The pageQuery
gets us the data for the data
prop.
Conclusion
We can render one or more Markdown files in our Gatsby project.