Gatsby: [v2] IE11 throws Objects are not valid as a React child

Created on 4 Aug 2018  ·  45Comments  ·  Source: gatsbyjs/gatsby

Description

When visiting sites using v2 in IE11 React throws an error

Steps to reproduce

Visit https://next.gatsbyjs.org in IE11 and check the console

Expected result

No errors

Actual result

React throws this error;

Objects are not valid as a React child (found: object with keys {$$typeof, type, key, ref, props, _owner}).

Environment

  System:
    OS: macOS High Sierra 10.13.6
    CPU: x64 Intel(R) Core(TM) i7-4870HQ CPU @ 2.50GHz
    Shell: 5.3 - /bin/zsh
  Binaries:
    Node: 8.11.3 - ~/.nvm/versions/node/v8.11.3/bin/node
    Yarn: 1.9.2 - /usr/local/bin/yarn
    npm: 5.6.0 - ~/.nvm/versions/node/v8.11.3/bin/npm
  Browsers:
    Chrome: 68.0.3440.84
    Firefox: 61.0.1
    Safari: 11.1.2
  npmPackages:
    gatsby: ^2.0.0-beta.64 => 2.0.0-beta.67 
    gatsby-plugin-catch-links: ^2.0.2-beta.5 => 2.0.2-beta.5 
    gatsby-plugin-feed: next => 2.0.0-beta.4 
    gatsby-plugin-glamor: next => 2.0.0-beta.3 
    gatsby-plugin-google-analytics: next => 2.0.0-beta.3 
    gatsby-plugin-manifest: next => 2.0.2-beta.3 
    gatsby-plugin-netlify: next => 2.0.0-beta.5 
    gatsby-plugin-nprogress: next => 2.0.0-beta.4 
    gatsby-plugin-react-helmet: next => 3.0.0-beta.4 
    gatsby-plugin-sharp: next => 2.0.0-beta.7 
    gatsby-plugin-twitter: next => 2.0.0-beta.3 
    gatsby-remark-autolink-headers: next => 2.0.0-beta.5 
    gatsby-remark-code-repls: next => 2.0.0-beta.4 
    gatsby-remark-copy-linked-files: next => 2.0.0-beta.3 
    gatsby-remark-embed-snippet: next => 3.0.0-beta.3 
    gatsby-remark-images: next => 2.0.1-beta.9 
    gatsby-remark-prismjs: next => 3.0.0-beta.5 
    gatsby-remark-responsive-iframe: next => 2.0.0-beta.3 
    gatsby-remark-smartypants: next => 2.0.0-beta.3 
    gatsby-source-filesystem: next => 2.0.1-beta.10 
    gatsby-transformer-remark: next => 2.1.1-beta.5 
    gatsby-transformer-sharp: next => 2.1.1-beta.6 

File contents (if changed)

gatsby-config.js: N/A
package.json: N/A
gatsby-node.js: N/A
gatsby-browser.js: N/A
gatsby-ssr.js: N/A

maintenance

Most helpful comment

The solution for my GatsbyJS [V2] broken production build for IE11 was;

$ npm i --save @babel/polyfill

then...

I worked around this by adding the babel polyfills as a webpack entry point in gatsby-node.js:

exports.onCreateWebpackConfig = ({
  stage,
  getConfig,
  actions: { replaceWebpackConfig }
}) => {
  switch (stage) {
    case 'build-javascript':
      // We want to include the babel polyfills before any application code,
      // so we're inserting it as an additional entry point.  Gatsby does not allow
      // this in "setWebpackConfig", so we have to use "replaceWebpackConfig"
      const config = getConfig();

      const app =
        typeof config.entry.app === 'string'
          ? [config.entry.app]
          : config.entry.app;

      config.entry.app = ['@babel/polyfill', ...app];
      replaceWebpackConfig(config);
  }
};

then...

$ gatsby build

Cheers @stripeyjumper

All 45 comments

This does not occur in the starter project and another project which I'm working on.
Is this gatsbyjs.org specific? Or do you have any other repo/site which has this issue?

No it's not gatsbyjs.org specific because I first noticed it when migrating reactjs.org (preview link) to v2. Here is the repo for that if you need it.

My best guess would be that polyfills aren't loaded correctly, like the Symbol polyfill which is required for React. Think I've seen this error before on a non-gatsby site and adding the correct polyfills solved that. Also I think the reason why you don't get any errors is because you might not use fragments or return arrays?

Here is an issue that might help https://github.com/facebook/react/issues/8379

/cc @pieh @KyleAMathews @m-allanson

I worked around this by adding the babel polyfills as a webpack entry point in gatsby-node.js:

exports.onCreateWebpackConfig = ({
  stage,
  getConfig,
  actions: { replaceWebpackConfig }
}) => {
  switch (stage) {
    case 'build-javascript':
      // We want to include the babel polyfills before any application code,
      // so we're inserting it as an additional entry point.  Gatsby does not allow
      // this in "setWebpackConfig", so we have to use "replaceWebpackConfig"
      const config = getConfig();

      const app =
        typeof config.entry.app === 'string'
          ? [config.entry.app]
          : config.entry.app;

      config.entry.app = ['@babel/polyfill', ...app];
      replaceWebpackConfig(config);
  }
};

I just did a build and the Symbol polyfill is in there

screenshot 2018-08-08 10 59 49

Hmm could it be Map or Set that is missing then? Also noticed that the site doesn't work at all in IE11 when you run gatsby develop, same error though

From reading https://github.com/facebook/react/issues/8379#issuecomment-264858787 one possibility is that the polyfill is loading _after_ React which could be happening since we're relying on Babel 7's polyfilling which adds polyfill imports as they're needed — which wouldn't actually be working since we don't run React through Babel.

Ah yeah, confirmation https://github.com/babel/babel/issues/7335#issuecomment-363209373

So we need to manually add the necessary polyfills to ensure they're run first.

One way to do this is to a) add the polyfills directly at the top of production-app.js (our entry) and then b) in our webpack config, look at what browsers people are supporting — if they're not supporting ie11 or below then we remove those polyfills.

Thoughts?

Anyone want to tackle this?

How would we be able to remove them in the webpack config though 🤔

I suppose you mean like this

// production-app.js
import '@babel/polyfill'
// or just the necessary polyfills
import 'core-js/es6/set'
import 'core-js/es6/map'

Then AFAIK there is no way to remove them, I could be wrong though

Huh strange, always though Symbol was needed for React but that might not the case https://reactjs.org/docs/javascript-environment-requirements.html

I could take this on, but unfortunately I won't have time until the weekend-ish. So if anyone else wanna grab this feel free to do so!

Oh cool, didn't know you could do that!

It's a neat trick :-)

If the babel settings for babel-preset-env were changed to useBuiltIns: 'entry', would that cause babel to include the polyfills according to the browserslist settings?

That's what the docs suggest, but I haven't tried it.
https://babeljs.io/docs/en/next/babel-preset-env.html#usebuiltins

Weird, I can no longer reproduce this in the production build, everything seems to be working now 🤷‍♂️

Still get errors in development though but I think this is intended right?

// .babel-preset.js
  const browserConfig = {
    useBuiltIns: false,
    targets: {
      browsers: PRODUCTION
        ? [`last 4 versions`, `safari >= 7`, "ie >= 9"]
        : [`last 2 versions`, `not ie <= 11`, `not android 4.4.3`],
    },
  }

Huh that is weird!

That bit of code is for compiling the Gatsby owned code. For compiling your code, this is where babel is setup https://github.com/gatsbyjs/gatsby/blob/98caef555360c777ae1e6527604af62634054270/packages/gatsby/src/internal-plugins/load-babel-config/utils.js#L51-L66

Oh I see!

Seems like I can't really figure this one out to be honest... it should technically work if I add this right?

// my-gatsby-site/.cache/app.js
import 'core-js/es6/map'
import 'core-js/es6/set'
...

If I add a console.log that get printed so I'm not really sure what's happening

I'm seeing this issue too after recently upgrading to v2. Here's some relevant snippets that might help y'all:

package.json

"dependencies": {
    "axios": "0.18.0",
    "babel-runtime": "6.26.0",
    "intersection-observer": "0.5.0",
    "prop-types": "15.6.2",
    "react": "16.4.2",
    "react-dom": "16.4.2",
    "react-dropdown": "1.5.0",
    "react-helmet": "5.2.0",
    "react-tabs": "2.2.2"
  },
  "devDependencies": {
    "aws-sdk": "2.283.1",
    "babel-core": "6.26.3",
    "babel-eslint": "8.2.6",
    "babel-jest": "23.4.2",
    "babel-loader": "7.1.5",
    "babel-polyfill": "6.26.0",
    "babel-preset-env": "1.7.0",
    "babel-preset-es2015": "6.24.1",
    "babel-preset-react": "6.24.1",
    "babel-preset-stage-0": "6.24.1",
    "enzyme": "3.3.0",
    "enzyme-adapter-react-16": "1.1.1",
    "eslint": "4.18.1",
    "eslint-config-payscale": "1.0.3",
    "eslint-plugin-react": "7.10.0",
    "eslint-teamcity": "1.4.0",
    "gatsby": "2.0.0-beta.93",
    "gatsby-module-loader": "2.0.0-alpha.3",
    "gatsby-plugin-google-tagmanager": "2.0.0-beta.3",
    "gatsby-plugin-react-helmet": "2.0.11",
    "gatsby-plugin-sass": "2.0.0-beta.6",
    "gatsby-source-aem": "1.8.8",
    "gatsby-source-filesystem": "2.0.1-beta.10",
    "gatsby-source-wordpress": "2.0.93",
    "gatsby-transformer-json": "2.1.1-beta.4",
    "jest": "23.4.2",
    "jest-teamcity-reporter": "0.9.0",
    "node-sass": "4.9.2",
    "react-test-renderer": "16.4.1"
  }

gatsby-browser.js

const getPolyfills = () => {
  if (!('IntersectionObserver' in window)) {
    require('intersection-observer');
  }
};

exports.onClientEntry = () => {
  getPolyfills();
};

gatsby-config.js

plugins: [
    'gatsby-plugin-sass',
    'gatsby-plugin-react-helmet',
    'gatsby-transformer-json',
    // other plugins that aren't relevant

Nothing in gatsby-node.js besides createPages

Windows 10, node 8.9.4

I am getting this error on the production build in V1..
develop works fine..

upgrading to V2 works in production but not in develop

I was able to resolve the error on localhost by following @stripeyjumper's 2nd comment https://github.com/gatsbyjs/gatsby/issues/7003#issuecomment-411388013 and adding a bit more.

  1. npm i @babel/polyfill --save-dev
  2. Created a .babelrc file in the project root and pasted in the sample file from the gatsby website https://www.gatsbyjs.org/docs/babel/#how-to-use-a-custom-babelrc-file
  3. Changed line 8 from useBuiltIns: "usage" to useBuiltIns: "entry"
  4. Added import "@babel/polyfill" at the top of gatsby-browser.js
  5. run gatsby develop to view http://localhost:8000/ in IE

I tried @stripeyjumper's 1st comment https://github.com/gatsbyjs/gatsby/issues/7003#issuecomment-411351268 but I still see an error in IE11 in production

Expected ':' 
TypeError: Object doesn't support this action 

I am not sure why this workaround works locally, or how to get it to work on production.

I'm seeing this error in V2 as well.

I'm also getting a mysterious new error in IE11 with gatsby v2.0.8 that reads:

Unhandled promise rejection Typeerror: Object doesn't support this action.

Edit: I tried adding @babel/polyfill to gatsby-browser.js, but the error still occurs.

I tried @sarahannnicholson's approach and can confirm that when running gatsby develop, there are no console errors in IE11, but when running gatsby build, I get the same errors as @sarahannnicholson.

But I don't get any errors in IE11 when I run gatsby build --no-uglify

Yes, I tried --no-uglify with gatsby build too and it works in IE 11.

The solution for my GatsbyJS [V2] broken production build for IE11 was;

$ npm i --save @babel/polyfill

then...

I worked around this by adding the babel polyfills as a webpack entry point in gatsby-node.js:

exports.onCreateWebpackConfig = ({
  stage,
  getConfig,
  actions: { replaceWebpackConfig }
}) => {
  switch (stage) {
    case 'build-javascript':
      // We want to include the babel polyfills before any application code,
      // so we're inserting it as an additional entry point.  Gatsby does not allow
      // this in "setWebpackConfig", so we have to use "replaceWebpackConfig"
      const config = getConfig();

      const app =
        typeof config.entry.app === 'string'
          ? [config.entry.app]
          : config.entry.app;

      config.entry.app = ['@babel/polyfill', ...app];
      replaceWebpackConfig(config);
  }
};

then...

$ gatsby build

Cheers @stripeyjumper

Ok I have been getting the same issues on my site.

However I have tried all the above but only --no-uglify fixes it for me in IE.

Adding the new Webpack config to gatsby-node.js does nothing for me.

Is there any plan going ahead for how to do this without disabling uglification?

Would really appreciate this.

I am using Material UI and I was experiencing the same issue. I resolved it by removing a CSS attribute that had an empty value. If you are using Material UI and Gatsby V2, this may be helpful for you in troubleshooting the problem.

I had a the following attribute in one of my components.

const styles = theme => ({
 root:{
  content:"",
 }
})

IE11 was giving me this error in the console when that attribute value was an empty string. Adding an attribute value solved the problem.

const styles = theme => ({
 root:{
  content:"x",
 }
})

I'm not sure why this resolved the issue. Maybe someone can explain it.

Also. I may be setting something up incorrectly, but I was only able to test this by using a production build. The site will not work in dev mode on ie11. It made for a very tedious and late night debugging session.

@KyleAMathews Sorry to be an utter pain here. Don't want to be THAT developer but I have no idea currently how to fix this issue aside from turning off uglification.

The project I am using Gatsby in for an accessibility company, so using Gatsby in our own products would be a great push for the accessibility possibilities of the tool itself.

However, not working in IE11 could very well be a deal breaker. Yes, I can get it working without uglification but that almost doubles the JS payload size.

If this is in the pipeline to be fixed, or there is another, less hacky fix, it is all good. I just need to know.

If I had any idea exactly which part of the code was killing IE I would really have been more helpful but I cannot even get the dev environment started in IE, so that leaves cryptic messages and tons of minified code to try and wade through.

If there is anything I can do to help please let me know.

Echoing the sentiment. I finally had the time to upgrade our website to Gatsby 2, but am unable to merge the changes since the site now doesn't work on IE11.

I can also try to help if there's anything I can do to track down the issue.

I've just checked www.gatsbyjs.org on IE11 and it works (built with [email protected]. So we probably need some reproductions to pinpoint where and why this is happening and determine if this is something we can try to fix

@pieh I am getting the issue only when I try to insert a component that is meant to be functional at runtime. If the page is purely "static" I do not see the issue.

I will see if I can reproduce with code that I can share at this stage.

@pieh I am unable to create a simple reproduction of the issue. Tried the usual suspects but they are not creating the issue.

From the issue I thought this was a more general problem.

Will need to completely break apart the component where this is going wrong. So will dig into that later.

@AlmeroSteyn I found that

Adding the new Webpack config to gatsby-node.js does nothing for me.

Didn't work for me as well.

You mentioned

I cannot even get the dev environment started in IE

Myself and others have had success running locally by following these instructions https://github.com/gatsbyjs/gatsby/issues/7003#issuecomment-424960907 . Have you given it a try?

@sarahannnicholson I dunno what I did the previous time around and which one of the fixes for IE11 dev mode I tried but yours works. Thank you!!!

I now have the same situation as you, works in dev, not in prod.

Gonna see this morning if I can narrow it down adding some realtime functionality works and others don't.

@pieh @DSchau I seem to have pinpointed the offending code.

It seems that this happens using a child render prop and then combining a props spread operator with setting another prop from the parameter of the render function.

The following code reproduces the issue on my side:

import React from 'react'

class TestRenderer extends React.Component {
  render() {
    return this.props.children('testValue')
  }
}

class TestAcceptor extends React.Component {
  render() {
    return (
      <div>
        {this.props.t}
        {this.props.s}
      </div>
    )
  }
}

const Combinator = props => (
  <TestRenderer>{t => <TestAcceptor t={t} {...props} />}</TestRenderer>
)

export default Combinator

If I import and use this in my index.js file, it throws the following errors on console in IE11 when using the uglified code:

SCRIPT1003: Expected ':'

and

Unhandled promise rejection TypeError: Object doesn't support this action

This is the exact same scenario that also triggers it in my production application.

I have also tried the following scenarios and they all worked fine:

const Combinator = props => (
  <TestRenderer>{t => <TestAcceptor {...props} />}</TestRenderer>
)
const Combinator = props => (
  <TestRenderer>{t => <TestAcceptor t={t} />}</TestRenderer>
)
const Combinator = props => (
  <TestAcceptor t="testValue" {...props} />
)

So it really seems that this only happens in a render prop.

I hope this helps as it would be really great to get this fixed.

Note: The same component works fine without console errors in the production build of create-react-app v2.

@AlmeroSteyn Would you be able to apply changes from https://github.com/gatsbyjs/gatsby/pull/9135 to your gatsby (in node_modules/gatsby/dist/utils/webpack-utils.js - it will be transpiled, so might be hard to read - but you should find terserOptions there) and see if it fixes it? This PR port setup from create-react-app, so possibly this is the problem we have.

@pieh Oh that fixes it alright! Awesome!

If I apply those settings, my production app works with minification and has a clean console.

Please merge :-)

I had the same issues as described above in IE11 on v2, and installing gatsby-plugin-polyfill-io fixed it for me. It now runs fine locally and builds fine too.

@pieh I applied the changes from PR #9135 too and it definitely fixed it for me as well. My app's working fine in IE 11 with no console errors. :)

Linked PR was merged and published in [email protected] so please update ;)

@pieh Thanks you! Test drove it this morning and all good now. Thanks for jumping on it so quickly.

Pinging @DSchau. We talked yesterday about this error still being thrown in development builds. It looks it might be caused by browsersList not getting set properly in dev mode. Maybe warrants this issue being reopened, please let me know and I can file a new issue.

@thetre97 👋 Working on this now!

I still have this issue with Gatsby v2.0.76 in IE11 (thrown by react-dom).

Edit: conditionally loading polyfill.io features in onClientEntry like this does not even fix the issue:

export const onClientEntry = () =>
  new Promise((resolve, reject) => {
    const features = []

    const isIE = /MSIE|Trident/.test(navigator.userAgent)

    let src = 'https://cdn.polyfill.io/v2/polyfill.min.js?callback=__polyfillCallback'

    if (!isIE) {
      if (!('Set' in window)) {
        features.push('Set')
      }

      if (!('Map' in window)) {
        features.push('Map')
      }

      if (!('Intl' in window)) {
        features.push('Intl.~locale.fr')
        features.push('Intl.~locale.en')
        features.push('Intl.~locale.es')
      }

      if (!('fetch' in window)) {
        features.push('fetch')
      }

      if (!('URL' in window && 'URLSearchParams' in window)) {
        features.push('URL')
      }

      if (!features.length) {
        resolve()
        return
      }

      src += `&features=${features.join(',')}`
    }

    window.__polyfillCallback = resolve
    const tag = document.createElement('script')
    tag.src = src
    tag.async = true
    tag.onerror = reject
    document.head.appendChild(tag)
  })

I see https://cdn.polyfill.io/v2/polyfill.min.js?callback=__polyfillCallback being loaded in IE11 but the error still shows up.

The only way I found is:

setHeadComponents([<script src="https://cdn.polyfill.io/v2/polyfill.min.js" />])

But it means it will always be loaded: I would like to avoid it in modern browsers!

@antoinerousseau 's solution - though somewhat 'unconventional' - was so far the only way for me to get an IE11 compatible site running. Hope a better solution will be available soon (or IE go away, whichever happens first).

I was able to resolve the error on localhost by following @stripeyjumper's 2nd comment #7003 (comment) and adding a bit more.

  1. npm i @babel/polyfill --save-dev
  2. Created a .babelrc file in the project root and pasted in the sample file from the gatsby website https://www.gatsbyjs.org/docs/babel/#how-to-use-a-custom-babelrc-file
  3. Changed line 8 from useBuiltIns: "usage" to useBuiltIns: "entry"
  4. Added import "@babel/polyfill" at the top of gatsby-browser.js
  5. run gatsby develop to view http://localhost:8000/ in IE

I tried @stripeyjumper's 1st comment #7003 (comment) but I still see an error in IE11 in production

Expected ':'
TypeError: Object doesn't support this action
I am not sure why this workaround works locally, or how to get it to work on production.

Been trying to make gatsby develop work in IE 11 using this but still not working.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ferMartz picture ferMartz  ·  3Comments

rossPatton picture rossPatton  ·  3Comments

brandonmp picture brandonmp  ·  3Comments

signalwerk picture signalwerk  ·  3Comments

jimfilippou picture jimfilippou  ·  3Comments