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,
},
})
})
}
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.