skip to Main Content

I’m trying to create dynamic product page in Gatsby.
Here is what I’ve edited in file gatsby-node.js

exports.createPages = async ({ graphql, actions }) => {
  const { createRedirect } = actions
  const { createPage } = actions

  const {
    data: { products },
  } = await graphql(`
    {
      products: allTestJson {
        edges {
          node {
            brand
            category
          }
        }
      }
    }
  `)

  const nodeArray = products.edges.map(edge => edge.node.brand)
  const unique = [...new Set(nodeArray)]
  console.log("UNIQUE")
  console.log(unique)

  unique.forEach((brand) => {
    console.log("BRAND")
    console.log(brand)
    createPage({
      path: `/products/${brand}`,
      component: require.resolve(`./src/pages/contact-us.js`),
    })
  })
}    

Here I do the console.log and I’m sure the ${node.brand} returns a value. (One of it is "faro"). However, when I visit /products/faro on the browser, I only see a big white blank page:

enter image description here

When I change the path to path: "path: /products/faro" (just hard code path as products/faro), then the page component renders correctly.

enter image description here

Is there something wrong with the loop or variable? I’m following this tutorial https://dev.to/notrab/build-static-product-pages-with-gatsby-and-commerce-js-3952

import React, { Component } from "react"
import styled from "styled-components"
import { injectIntl, Link, FormattedMessage } from "gatsby-plugin-intl"

import Layout from "../components/layout"
import SEO from "../components/seo"
import { Background } from "../components/layout/Background"
import { Space } from "../components/layout/Space"
import ShowroomGrid from "../components/organisms/ShowroomGrid"
import ContactForm from "../components/organisms/ContactForm"
import Map from "../components/molecules/Map"

class ContactUs extends Component {
  state = {
    responsiveSize: null,
  }

  componentDidMount = () => {
    this.setState({
      responsiveSize: window.innerWidth,
    })
  }

  render() {
    const { responsiveSize } = this.state
    return (
      <Layout>
        <SEO
          description="Visit our showrooms in Ho Chi Minh City & Hanoi to admire the timeless masterpieces from Fritz Hansen, Flos, Louis Poulsen, Fontana Arte & Faro."
          title="Contact Us - nanoHome showrooms in HCM & Hanoi"
          keywords={[`luxury`, `lighting`, `furniture`, `showroom`]}
        />
        <Background>
          <MainContainer className="main-container">
            <Space height="64" />
            <H1Tag>nanoHome | Contact Us</H1Tag>
            <SectionMapAndContact responsiveSize={responsiveSize}>
              <GoogleMap>
                <Map />
              </GoogleMap>
              <Contacts>
                <Title>
                  <FormattedMessage id="page-contact-us.section-map-and-contact.title" />
                </Title>
                <Space height="48" />
                <Address>
                  <b>
                    <FormattedMessage id="page-contact-us.section-map-and-contact.office" /> </b> <Space height="16" />
                  <p>
                  <FormattedMessage id="page-contact-us.section-map-and-contact.address" />
                  </p>
                  <Space height="16" />
                  <p>‭+84 90 984 0028</p>
                  <Space height="8" />
                  <p>[email protected]</p>
                  <Space height="8" />
                  <p>www.nanohome.vn</p>
                </Address>
              </Contacts>
            </SectionMapAndContact>
            <Space height="64" />
            <SectionShowrooms>
              <Title>Our Showrooms</Title>
              <Space height="48" />
              <ShowroomGrid responsiveSize={responsiveSize} />
            </SectionShowrooms>
            <Space height="64" />
            <SectionContactForm responsiveSize={responsiveSize}>
              <Title>Get in Touch</Title>
              <Space height="48" />
              <ContactForm />
            </SectionContactForm>
          </MainContainer>
        </Background>
      </Layout>
    )
  }
}

const MainContainer = styled.div`
  margin: 0 auto;
`

const SectionMapAndContact = styled.div`
  max-width: 960px;
  margin: auto;
  padding: 0 2rem;
  display: grid;
  grid-template-columns: ${props =>
    props.responsiveSize > 1024 ? "1fr 1fr" : "1fr"};
  grid-template-rows: ${props =>
    props.responsiveSize < 1024 ? "1fr auto" : "1fr"};
  align-items: center;
  justify-content: center;
  grid-gap: ${props => (props.responsiveSize > 1024 ? "4rem" : "2rem")};
`
const GoogleMap = styled.div`
  width: 100%;
  height: 500px;
`
const Contacts = styled.div`
  width: 100%;
  max-width: 440px;
`
const Title = styled.h2`
  font-size: var(--font-size-larger);
  color: var(--color-primary-blue);
  font-family: "Miller";
`
const Address = styled.div`
  color: var(--color-primary-blue);
  font-size: var(--font-size-large);
  border-left: 2px solid var(--color-primary-blue);
  padding: 0 2rem;
  p {
    font-size: var(--font-size-medium);
    line-height: 1.5;
    margin: 0;
  }
`
const SectionShowrooms = styled.div`
  padding: 0 2rem;
  max-width: 960px;
  margin: auto;
`

const SectionContactForm = styled.div`
  width: ${props =>
    (props.responsiveSize > 1024 && "24%") ||
    (props.responsiveSize > 768 && "50%") ||
    (props.responsiveSize > 480 && "80%") ||
    "100%"};
  margin: auto;
  max-width: 960px;
  padding: 0 2rem;
  min-width: 320px;
  display: flex;
  flex-direction: column;
  align-items: center;
`

const H1Tag = styled.h1`
  visibility: hidden;
  font-size: var(--font-size-smaller);
`

export default ContactUs

I also add the debug of unique Array and brand here (sorry it’s quite messy as I’m outside)
enter image description here

2

Answers


  1. Chosen as BEST ANSWER

    The problem is the "brand data" that I loaded from graphql has some capital letters, and the browser always lowercase text, so it does not match the path in gatsby-node.js. Thank you @harley for spotting this. Thank you for all your help.


  2. The fact that you’re not getting a 404 page indicates that your page is being created correctly.

    Is it possible the page is expecting some sort of props? In the tutorial you linked, it looks like they are passing an id prop. To pass such props you need to pass a context arg to createPage (eg. createPage({ component, path, context: { id })) … but the code you provided doesn’t have any.

    Whatever the problem is, it seems likely that it’s in contact-us.js, so you’ll need to debug it.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search