DEV Community

Pacharapol Withayasakpunt
Pacharapol Withayasakpunt

Posted on

Gatsby Dynamic Page Creation is the Key for Blogs

Continuing from

Apparently, everything a blog requires, is dynamic page creation. The official tutorial is here. -- https://www.gatsbyjs.org/tutorial/part-seven/

How I did it

  • Firstly, I moved /src/pages/index.tsx to /src/templates/Listing.tsx. Basically, I am gonna use it for template.
  • I also created /src/templates/Post.tsx to use to create posts.
  • There are two magics on gatsby-node.js for this,
    • exports.createPages
    • exports.onCreateNode
  • You should inspect what slug entails, in case you want to customize it.
exports.createPages = async ({ graphql, actions, reporter }) => {
  const { createPage } = actions
  const result = await graphql(
    `
      {
        allMarkdownRemark(
          sort: { fields: [frontmatter___date], order: DESC }
        ) {
          edges {
            node {
              fields {
                slug
              }
            }
          }
        }
      }
    `)
  if (result.errors) {
    reporter.panicOnBuild('Error while running GraphQL query.')
    return
  }

  const posts = result.data.allMarkdownRemark.edges
  const postsPerPage = 5
  const numPages = Math.ceil(posts.length / postsPerPage)
  Array.from({ length: numPages }).forEach((_, i) => {
    createPage({
      path: i === 0 ? '/' : `/page/${i + 1}`,
      component: path.resolve('./src/templates/Listing.tsx'),
      context: {
        limit: postsPerPage,
        skip: i * postsPerPage,
        currentPage: i + 1,
      },
    })
  })

  posts.forEach((p) => {
    createPage({
      path: `/posts${p.node.fields.slug}`,
      component: path.resolve('./src/templates/Post.tsx'),
      context: {
        slug: p.node.fields.slug,
      },
    })
  })
}

exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions
  if (node.internal.type === 'MarkdownRemark') {
    const value = createFilePath({ node, getNode })
    createNodeField({
      name: 'slug',
      node,
      value,
    })
  }
}
Enter fullscreen mode Exit fullscreen mode

Bonus

I am also trying to find out how to lazy load images and and iframes. I ended up using

Again, my example repo is here

GitHub logo patarapolw / non-root-gatsby-blog

An attempt to create a Gatsby blog as a part of Monorepo, with /data and /dist (output-dir) directories sticking out, instead of being inside the Gatsby repo.

Top comments (0)