Search code examples
node.jsbuildgraphqlgatsbyproduction

gatsby develop works but not build on same project


I have a very simple Gatsby application. I am running gatsby develop on that and it works fine but when I run gatsby build I am getting an error. I am not sure why the develop would work and the build wouldn't. Not sure what I am missing!

import React from "react"

import Layout from "./layout"

const ProductTemplate = ({ pageContext }) => {
const { product } = pageContext
return (
  <Layout>
    <h1>{product.title}</h1>
    <div>{product.description}</div>

  </Layout>
  )
}

export default ProductTemplate

This is the exact error

   8 |   return (
   9 |     <Layout>
> 10 |       <h1>{product.title}</h1>
     |                    ^
  11 |       <div>{product.description}</div>
  12 | 


  WebpackError: TypeError: Cannot read property 'title' of undefined

  - product.js:10 
  src/pages/product.js:10:20

gatsby-node.js

const path = require(`path`)
exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions
// Query for all products in Shopify
const result = await graphql(`
  query {
    allShopifyProduct(sort: { fields: [title] }) {
      edges {
        node {
          title
          shopifyId
          handle
          description
          availableForSale
          priceRange {
            maxVariantPrice {
              amount
            }
            minVariantPrice {
              amount
            }
          }
        }
      }
    }
  }
`)
// Iterate over all products and create a new page using a template
// The product "handle" is generated automatically by Shopify
result.data.allShopifyProduct.edges.forEach(({ node }) => {
  createPage({
    path: `/product/${node.handle}`,
    component: path.resolve(`./src/pages/product.js`),
    context: {
      product: node,
    },
  })
})
}

Solution

  • Your ProductTemplate is inside /pages folder (it should be in /templates). This is causing that Gatsby tries to create pages for each of the files in that directory automatically. In the case where it does so automatically, it doesn't get any context, and hence build fails. This only happens when you run gatsby build because during the gatsby develop there's no SSR (Server-Side Rendering).

    createPage API is intended to create dynamic pages based on a slug, path, or another unique identifier field, not for known pages like the ones that are inside /pages folder.

    To fix it, just move your product.js to /templates and change this:

    component: path.resolve(`./src/pages/product.js`),
    

    To this:

    component: path.resolve(`./src/templates/product.js`),
    

    This is because you are creating a template for each product, not a page (like Gatsby understands a page).

    Here's a GitHub thread with exactly your issue if you want to follow the full explanation.