gatsby: wrapPageElement is not working when being exported using CommonJS syntax

Description

wrapPageElement is failing to render when being used in gatsby-browser.js and not working when being used in gatsby-ssr.js.

Steps to reproduce

Export wrapPageElement from either gatsby-browser.js or gatsby-ssr.js

You can clone this repository which contains a reproduction of the bug https://github.com/jgalat/wrap-page-element-bug-reproduction

Expected result

Pages should be wrapped with the layout component.

Actual result

When exporting wrapPageElement from gatsby-browser.js and calling gatsby develop the site fails to render getting the following exception image When doing gatsby build && gatsby serve the exception disappears but the page isn’t wrapped with the layout component.

When exporting wrapPageElement from gatsby-ssr.js and calling gatsby develop the site renders but the pages aren’t being wrapped with the layout component. When doing gatsby build && gatsby serve, the site fails to compile showing the following error

success open and validate gatsby-configs — 0.008 s
success load plugins — 0.051 s
success onPreInit — 0.004 s
success delete html and css files from previous builds — 0.015 s
success initialize cache — 0.008 s
success copy gatsby files — 0.021 s
success onPreBootstrap — 0.007 s
success source and transform nodes — 0.014 s
success building schema — 0.144 s
success createPages — 0.000 s
success createPagesStatefully — 0.047 s
success onPreExtractQueries — 0.000 s
success update schema — 0.018 s
success extract queries from components — 0.013 s
success run static queries — 0.001 s
success run page queries — 0.009 s — 3/3 360.05 queries/second
success write out page data — 0.003 s
success write out redirect data — 0.000 s
success onPostBootstrap — 0.000 s

info bootstrap finished - 2.277 s

success Building production JavaScript and CSS bundles — 5.914 s

error Building static HTML failed for path "/404/"

See our docs page on debugging HTML builds for help https://gatsby.dev/debug-html

   8 | 	else
   9 | 		root["lib"] = factory(root["@reach/router"], root["core-js/modules/es6.array.iterator"], root["core-js/modules/es6.array.sort"], root["core-js/modules/es6.function.name"], root["core-js/modules/es6.map"], root["core-js/modules/es6.object.assign"], root["core-js/modules/es6.object.to-string"], root["core-js/modules/es6.regexp.constructor"], root["core-js/modules/es6.regexp.split"], root["core-js/modules/es6.regexp.to-string"], root["core-js/modules/es6.string.ends-with"], root["core-js/modules/es6.string.iterator"], root["core-js/modules/web.dom.iterable"], root["fs"], root["lodash"], root["path"], root["react"], root["react-dom/server"]);
> 10 | })(this, function(__WEBPACK_EXTERNAL_MODULE__reach_router__, __WEBPACK_EXTERNAL_MODULE_core_js_modules_es6_array_iterator__, __WEBPACK_EXTERNAL_MODULE_core_js_modules_es6_array_sort__, __WEBPACK_EXTERNAL_MODULE_core_js_modules_es6_function_name__, __WEBPACK_EXTERNAL_MODULE_core_js_modules_es6_map__, __WEBPACK_EXTERNAL_MODULE_core_js_modules_es6_object_assign__, __WEBPACK_EXTERNAL_MODULE_core_js_modules_es6_object_to_string__, __WEBPACK_EXTERNAL_MODULE_core_js_modules_es6_regexp_constructor__, __WEBPACK_EXTERNAL_MODULE_core_js_modules_es6_regexp_split__, __WEBPACK_EXTERNAL_MODULE_core_js_modules_es6_regexp_to_string__, __WEBPACK_EXTERNAL_MODULE_core_js_modules_es6_string_ends_with__, __WEBPACK_EXTERNAL_MODULE_core_js_modules_es6_string_iterator__, __WEBPACK_EXTERNAL_MODULE_core_js_modules_web_dom_iterable__, __WEBPACK_EXTERNAL_MODULE_fs__, __WEBPACK_EXTERNAL_MODULE_lodash__, __WEBPACK_EXTERNAL_MODULE_path__, __WEBPACK_EXTERNAL_MODULE_react__, __WEBPACK_EXTERNAL_MODULE_react_dom_server__) {
     |  ^
  11 | return 


  WebpackError: Invariant Violation: 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.
  
  - universalModuleDefinition:10 ba
    lib/webpack/universalModuleDefinition:10:2
  
  
  - bootstrap:33 a.render
    lib/webpack/bootstrap:33:1
  
  - bootstrap:30 a.read
    lib/webpack/bootstrap:30:1
  
  - bootstrap:42 renderToString
    lib/webpack/bootstrap:42:1
  
  - static-entry.js:206 Module.default
    lib/.cache/static-entry.js:206:18
  
  - bootstrap:24 Promise
    lib/webpack/bootstrap:24:1
  
  
  - static-entry.js:5 Promise._resolveFromExecutor
    lib/.cache/static-entry.js:5:48
  
  - bootstrap:68 new Promise
    lib/webpack/bootstrap:68:1
  
  
  - bootstrap:5 tryCatcher
    lib/webpack/bootstrap:5:1
  
  - bootstrap:50 MappingPromiseArray._promiseFulfilled
    lib/webpack/bootstrap:50:1
  
  - api-runner-ssr.js:8 MappingPromiseArray.PromiseArray._iterate
    lib/.cache/api-runner-ssr.js:8:1
  
  - bootstrap:67 MappingPromiseArray.init
    lib/webpack/bootstrap:67:1
  
  - bootstrap:19 MappingPromiseArray._asyncInit
    lib/webpack/bootstrap:19:1
  

Environment


  System:
    OS: Linux 5.0 Arch Linux undefined
    CPU: (4) x64 Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz
    Shell: 5.0.3 - /bin/bash
  Binaries:
    Node: 11.14.0 - /usr/bin/node
    Yarn: 1.15.2 - /usr/bin/yarn
    npm: 5.1.0 - ~/.yarn/bin/npm
  Languages:
    Python: 3.7.3 - /usr/bin/python
  Browsers:
    Firefox: 66.0.3
  npmPackages:
    gatsby: ^2.3.31 => 2.3.31 
    gatsby-image: ^2.0.40 => 2.0.40 
    gatsby-plugin-manifest: ^2.0.29 => 2.0.29 
    gatsby-plugin-offline: ^2.0.25 => 2.0.25 
    gatsby-plugin-react-helmet: ^3.0.12 => 3.0.12 
    gatsby-plugin-sharp: ^2.0.35 => 2.0.35 
    gatsby-source-filesystem: ^2.0.32 => 2.0.32 
    gatsby-transformer-sharp: ^2.1.18 => 2.1.18 

If you guys need anything more from my side I’ll be glad to help

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 1
  • Comments: 30 (23 by maintainers)

Most upvoted comments

Hi you can try switching require to import/export for both gatsby-ssr.js and gatsby-browser.js

import React from 'react';
import Layout from './src/components/layout';

export const wrapPageElement = ({ element, props }) => {
  return <Layout {...props}>{element}</Layout>;
};

Repro here https://codesandbox.io/s/v3qk6593o0

I guess browser’s es6 import/export and node module systems are not entirely compatible. I’m not super clear on the difference between those two. But my general rule of thumb is to use es6 import/export style for both gatsby-browser and gatsby-ssr.

Yes, you need to use both gatsby-ssr and gatsby-browser at the same time. In fact it’s even better if wrapPageElement.js is shared between them. You can take a look again at repro https://codesandbox.io/s/v3qk6593o0.

Using only one of them will cause a mismatch between the server-rendered version and the client version. That’s why you are seeing the layout disappears since the server-rendered version has the layout while the browser version does not.

When I say SSR, it is not that you hit a server and it will build a page at runtime, but rather it will build the page into static files and will use the SSR capabilities for all of the routes before it is deployed up to a web server

@waleedshkt correct - but we want to allow flexibility if we can! It’s not as simple as ES modules are newer than CommonJS, therefore they’re better–there’s reasons to choose either, and if we don’t have to break one for the other, we shouldn’t.

@lannonbr Gotcha 👍

One thing: in the official gatsby API guide docs, the examples given use require for importing like(e,g wrapePageElement api):

Feel silly 😜 reiterating what’s been already told in the thread above

const React = require("react")
const Layout = require("./src/components/layout")

exports.wrapPageElement = ({ element, props }) => {
  // props provide same data to Layout as Page element will get
  // including location, data, etc - you don't need to pass it
  return <Layout {...props}>{element}</Layout>
}

When running gatsby app, the above syntax gives errors. But when I use import/ export ES6 features, errors go away and the app works:

import React from "react";
import Layout from "./src/components/layout";
export const wrapPageElement = ({ element, props }) => {
  return (<Layout {...props}>{element}</Layout>);
}