Gatsby: Fails to build static html from dynamic pages build

Created on 22 Aug 2019  Â·  10Comments  Â·  Source: gatsbyjs/gatsby

Description

I'm dynamically generating pages from a json file, which works when I run gatsby develop but fails when I run gatsby build. The json file is pretty straightforward, and I loop through it in my gatsby-node file. I personally don't see what I'm doing wrong so I'm starting to believe it may be a bug in Gatsby.

The error I'm getting in the terminal is:

Building static HTML failed for path "/featured-icons/apple-icons"
See our docs page for more info on this error: https://gatsby.dev/debug-html



  Error: Minified React error #130; visit https://reactjs.org/docs/error-decoder  .html?invariant=130&args[]=object&args[]= for the full message or use the non-  minified dev environment for full errors and additional helpful warnings.

  - react-dom-server.node.production.min.js:47 a.render
    [iconjar-gatsby]/[react-dom]/cjs/react-dom-server.node.production.min.js:47:    349

  - react-dom-server.node.production.min.js:44 a.read
    [iconjar-gatsby]/[react-dom]/cjs/react-dom-server.node.production.min.js:44:    161

  - react-dom-server.node.production.min.js:55 renderToString
    [iconjar-gatsby]/[react-dom]/cjs/react-dom-server.node.production.min.js:55:    83

  - render-page.js:614 Module.default
    /Users/daveyheuser/iconjar-gatsby/public/render-page.js:614:28

  - render-html.js:35 Promise
    [iconjar-gatsby]/[gatsby]/dist/utils/worker/render-html.js:35:36

  - debuggability.js:313 Promise._execute
    [iconjar-gatsby]/[bluebird]/js/release/debuggability.js:313:9

  - promise.js:488 Promise._resolveFromExecutor
    [iconjar-gatsby]/[bluebird]/js/release/promise.js:488:18

  - promise.js:79 new Promise
    [iconjar-gatsby]/[bluebird]/js/release/promise.js:79:10

  - render-html.js:31 Promise.map.path
    [iconjar-gatsby]/[gatsby]/dist/utils/worker/render-html.js:31:37

  - util.js:16 tryCatcher
    [iconjar-gatsby]/[bluebird]/js/release/util.js:16:23

  - map.js:61 MappingPromiseArray._promiseFulfilled
    [iconjar-gatsby]/[bluebird]/js/release/map.js:61:38

  - promise_array.js:114 MappingPromiseArray.PromiseArray._iterate
    [iconjar-gatsby]/[bluebird]/js/release/promise_array.js:114:31

  - promise_array.js:78 MappingPromiseArray.init
    [iconjar-gatsby]/[bluebird]/js/release/promise_array.js:78:10

  - map.js:30 MappingPromiseArray._asyncInit
    [iconjar-gatsby]/[bluebird]/js/release/map.js:30:10

  - async.js:142 _drainQueueStep
    [iconjar-gatsby]/[bluebird]/js/release/async.js:142:12

  - async.js:131 _drainQueue
    [iconjar-gatsby]/[bluebird]/js/release/async.js:131:9

gatsby_node.js

const path = require(`path`)

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

  return new Promise((resolve, reject) => {
    const featuredIconsTemplate = path.resolve(`src/templates/featured-set.js`)
    resolve(
      graphql(
        `
          {
            allFeaturedIconsJson {
              edges {
                node {
                  slug
                }
              }
            }
          }
        `
      ).then(result => {
        if (result.errors) {
          reject(result.errors)
        }

        result.data.allFeaturedIconsJson.edges.forEach(({node})  => {
          createPage({
            path: `featured-icons/${node.slug}`,
            component: featuredIconsTemplate,
            context: {
              slug: node.slug
            },
          })
        })
      })
    )
  })
}

Snippet from my json

[
  {
    "name": "Icon set",
    "slug": "icon-set-1",
    "category": "free",
    "numberOfIcons": 60,
    "description": "This is the description",
    "author": {
      "name": "Name",
      "website": "http://www.google.com"
    },
    "downloadLinks": {
      "sample": "",
      "externalLink": ""
    }
  },
  {
    "name": "Icon set",
    "slug": "icon-set-2",
    "category": "free",
    "numberOfIcons": 231,
    "description": "This is the description",
    "author": {
      "name": "Name",
      "website": "https://www.google.com"
    },
    "downloadLinks": {
      "sample": "",
      "externalLink": ""
    }
  }
]

The build started to break when I move my application's Layout wrapper to the gatsby-ssr and gatsby-browser.js files.

gatsby-browser.js

var React = require("react")
var Layout = require("./src/components/Layout").default

exports.wrapPageElement = ({ element, props }) => {
  return <Layout {...props}>{element}</Layout>
}

gatsby-ssr.js

var React = require('react')
var Layout = require('./src/components/Layout')

exports.wrapPageElement = ({ element }) => {
  return <Layout>{element}</Layout>
}

Layout.js

import React from 'react'
import PropTypes from 'prop-types'
import Navigation from './Navigation'
import Footer from './Footer'
import ParallaxBg from './ParallaxBg'
import CookieNotice from './CookieNotice'
import { ThemeProvider } from 'styled-components'
import GlobalStyle from '../theme/globalStyles'

const Layout = ({ children }) => {

  return (
    <>
      <GlobalStyle light />
      <ThemeProvider theme={{ appearance: 'light' }}>
        <>
          <Navigation />
          <ParallaxBg />
          {children}
          <Footer />

          <CookieNotice />
        </>
      </ThemeProvider>
    </>
  )
}

Layout.propTypes = {
  children: PropTypes.node.isRequired
}

export default Layout

featured-set.js

import React from 'react'
import { graphql } from 'gatsby'
import SEO from '../components/SEO'
import Img from 'gatsby-image'
import styled from 'styled-components'

import Container from '../components/Container'
import { Flex, Box } from 'reflexbox'
import Card from '../components/Card'
import Button from '../components/Button'
import IconTwitter from '../images/vector/icon-twitter.svg'
import IconFacebook from '../images/vector/icon-facebook.svg'

const FeaturedSet = ({ props, data }) => {
  const setData = data.featuredIconsJson

  return (
    <>
      <SEO title={'Featured icons ∙ ' + setData.name} />

      <Container my={[4, 5]}>
        <Flex flexWrap="wrap">
          <Box width={[1, 2 / 5]} px={[0, 3]}>
            <h1>{setData.name}</h1>
            <p>
              Designed by{' '}
              <a href={setData.author.website}>{setData.author.name}</a>
            </p>
            <p>{setData.description}</p>

            <Flex mb={3}>
              {setData.downloadLinks.sample && (
                <Box pr={3}>
                  <Button
                    as="a"
                    href={data.sampleSet.edges[0].node.publicURL}
                    big>
                    Download sample
                  </Button>
                </Box>
              )}

              {setData.downloadLinks.externalLink && (
                <Box>
                  <Button
                    as="a"
                    href={setData.downloadLinks.externalLink}
                    colorscheme="green"
                    big>
                    Buy icon set
                  </Button>
                </Box>
              )}
            </Flex>
          </Box>
          <Box width={[1, 3 / 5]} px={[0, 3]}>
            <Card>
              <Img
                fluid={data.image.childImageSharp.fluid}
                style={{ width: '100%', display: 'block' }}
              />
            </Card>
          </Box>
        </Flex>
      </Container>
    </>
  )
}

export default FeaturedSet

export const pageQuery = graphql`
  query($slug: String!) {
    featuredIconsJson: featuredIconsJson(slug: { eq: $slug }) {
      name
      numberOfIcons
      description
      author {
        name
        website
      }
      downloadLinks {
        sample
        externalLink
      }
    }
    image: file(name: { eq: "detail@2x" }, relativeDirectory: { eq: $slug }) {
      childImageSharp {
        fluid(maxWidth: 640, quality: 100) {
          ...GatsbyImageSharpFluid_noBase64
        }
      }
    }
    sampleSet: allFile(
      filter: { extension: { eq: "zip" }, relativeDirectory: { eq: $slug } }
    ) {
      edges {
        node {
          publicURL
        }
      }
    }
  }
`

Environment

  System:
    OS: macOS 10.14.6
    CPU: (12) x64 Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
    Shell: 5.3 - /bin/zsh
  Binaries:
    Node: 11.11.0 - /usr/local/bin/node
    Yarn: 1.17.3 - /usr/local/bin/yarn
    npm: 6.10.1 - /usr/local/bin/npm
  Languages:
    Python: 2.7.10 - /usr/bin/python
  Browsers:
    Chrome: 76.0.3809.100
    Firefox: 65.0.2
    Safari: 12.1.2
  npmPackages:
    gatsby: ^2.13.19  => 2.13.76 
    gatsby-cli: ^2.7.13  => 2.7.37 
    gatsby-image: ^2.2.6 => 2.2.12 
    gatsby-plugin-manifest: ^2.2.0 => 2.2.8 
    gatsby-plugin-netlify: ^2.1.0 => 2.1.8 
    gatsby-plugin-react-helmet: ^3.1.0 => 3.1.4 
    gatsby-plugin-segment-js: ^3.0.1 => 3.0.1 
    gatsby-plugin-sharp: ^2.2.2 => 2.2.16 
    gatsby-plugin-styled-components: ^3.1.0 => 3.1.2 
    gatsby-source-filesystem: ^2.1.1 => 2.1.14 
    gatsby-transformer-json: ^2.2.0 => 2.2.4 
    gatsby-transformer-sharp: ^2.2.1 => 2.2.10 
  npmGlobalPackages:
    gatsby-cli: 2.7.15

Let me know if you need more info!

awaiting author response

Most helpful comment

@noudadrichem in a nutshell yes. I'm using the approach applied in other issues and using the information at hand.

I stand by my response. It all depends on how the author wishes to continue. And feel free to tackle any of the issues that are currently opened here.

All 10 comments

@daveyheuser can you create a reproduction following these steps so that it can be looked at in more detail? it could be something with react, gatsby or any other package that you have.

Yeah of course, is this enough to work with? https://codesandbox.io/embed/issue-16968-dhkhm

@daveyheuser checked the codesandbox link and it all looks fine, probably something more the cause and some extra information is needed. If you can adjust the sandbox to match the information you supplied in the description with all the packages you're using and components it would be better so that the issue could be pinpointed.

Hey thanks for looking into this! The error already exists with the current packages if you run the build script, the develop script works fine and runs just fine.

image

Try:
var Layout = require("./src/components/Layout").default
Instead of
var Layout = require("./src/components/Layout")
in gatsby-ssr.js

This works on my end: https://jmp.sh/CsmL5kQ

@daveyheuser i took a another look at your code and i think i have a solution for you.

  • Created a new gatsby site based on the codesandbox link you supplied, based on the hello world starter.
  • Added the necessary dependencies needed and now my package.json looks like:
 "dependencies": {
    "babel-plugin-styled-components": "^1.10.6",
    "gatsby": "^2.13.73",
    "gatsby-plugin-styled-components": "^3.1.3",
    "gatsby-source-filesystem": "^2.1.17",
    "gatsby-transformer-json": "^2.2.5",
    "react": "^16.9.0",
    "react-dom": "^16.9.0",
    "styled-components": "^4.3.2"
  },

I'm using only the ones that are directly implied on this issue and your codesandbox, the image, manifest plugins were not added as they were not needed, nor are they present in the codebase.

  • Copied over the file/folder structure to match yours.
  • Issued gatsby build && gatsby serve to get a production build and emulate the site as it was running on a production server and i'm presented with:
    davey_1

Which it seems that's the issue you're experiencing.

  • With that in mind i thought of applying the same approach as it's used in some examples while using a redux or mobx.
  • Created a file called wrap-with-provider.js with the following code:
import React from "react"
import Layout from "./src/components/Layout"

export default ({ element, props }) => <Layout {...props}>{element}</Layout>

  • Modified gatsby-browser.js and gatsby-ssr.js to the following:
import wrapWithProvider from "./wrap-with-provider"
export const wrapPageElement = wrapWithProvider
  • Modified src/components/Layout.js to see if it would actually process it through the apis, transforming it into:
import React from 'react'
import PropTypes from 'prop-types'
import { ThemeProvider } from 'styled-components'

const Layout = ({ children }) => {

  console.log(`layout was applied`)// layout console log to test out each page.
  return (
    <ThemeProvider theme={{ appearance: 'light' }}>
      <>
      <h1>This is a test website</h1>
      {children}
      </>
    </ThemeProvider>
  )
}

Layout.propTypes = {
  children: PropTypes.node.isRequired
}

export default Layout
  • Issued gatsby build && gatsby serve once more to check if everything was ok and i'm presented with:
    davey_2

  • Opened up http://localhost:9000/ and the page renders ok as you can see below:
    davey_3

The reason why it's happening with your code could be related to some transpiling or something completely diferent alltogether and for that i leave it to someone more knowledgeable of gatsby.
If you want i can hoist up this reproduction to a github repo so that you can take a look at it at your own pace.

Feel free to provide feedback so that we can close this issue, or continue to work on it until we find a suitable solution.

Great debug process! @jonniebigodes

What you're basically doing is the same as I said in my previous comment. You're making the <Layout /> function a default export. Only your way is to detract this into a seperate file/function that get's transpiled from es6 to es5.
The bug in @daveyheuser his codebase could be easily fixed to make the Layout a default export by adding .default to the require() function. It's basically the same thing.

@noudadrichem in a nutshell yes. I'm using the approach applied in other issues and using the information at hand.

I stand by my response. It all depends on how the author wishes to continue. And feel free to tackle any of the issues that are currently opened here.

Thanks Noud and Jonnie! Both approaches seem to work great 🙌.

We're marking this issue as answered and closing it for now but please feel free to reopen this and comment if you would like to continue this discussion. We hope we managed to help and thank you for using Gatsby! 💜

Was this page helpful?
0 / 5 - 0 ratings

Related issues

totsteps picture totsteps  Â·  3Comments

3CordGuy picture 3CordGuy  Â·  3Comments

magicly picture magicly  Â·  3Comments

dustinhorton picture dustinhorton  Â·  3Comments

dustinhorton picture dustinhorton  Â·  3Comments