WebpackError: ReferenceError: btoa is not defined

Getting this error when building in a dev environment using GatsbyJS:

 ERROR 

There was an error compiling the html.js component for the development server.
See our docs page on debugging HTML builds for help https://gatsby.dev/debug-html ReferenceError: btoa is not defined


  21 | }
  22 | else {
> 23 |     _btoa = btoa.bind(window);
     | ^
  24 |     helpers = function (url) {
  25 |         return new URL(url);
  26 |     };


  WebpackError: ReferenceError: btoa is not defined
  
  - helpers.js:23 
    [eh]/[web3-providers-ws]/lib/helpers.js:23:1
  
  - bootstrap:19 
    eh/webpack/bootstrap:19:1
  
  - index.js:24 
    [eh]/[web3-providers-ws]/lib/index.js:24:15
  
  - bootstrap:19 
    eh/webpack/bootstrap:19:1
  
  - index.js:45 
    [eh]/[web3-core-requestmanager]/lib/index.js:45:24
  
  - bootstrap:19 
    eh/webpack/bootstrap:19:1
  
  - index.js:22 
    [eh]/[web3-core]/lib/index.js:22:24
  
  - bootstrap:19 
    eh/webpack/bootstrap:19:1
  
  - index.js:29 
    [eh]/[web3]/lib/index.js:29:12
  
  - bootstrap:19 
    eh/webpack/bootstrap:19:1
  
  - MoralisWeb3.js:35 
    [eh]/[moralis]/lib/browser/MoralisWeb3.js:35:35
  
  - bootstrap:19 
    eh/webpack/bootstrap:19:1
  
  - ParseUser.js:51 
    [eh]/[moralis]/lib/browser/ParseUser.js:51:42
  
  - bootstrap:19 
    eh/webpack/bootstrap:19:1
  
  - ParseACL.js:25 
    [eh]/[moralis]/lib/browser/ParseACL.js:25:41
  
  - bootstrap:19 
    eh/webpack/bootstrap:19:1
  

not finished Building development bundle - 6.829s

link to the branch: https://github.com/iammatthias/.com/tree/moralis

related info: https://github.com/ChainSafe/web3.js/issues/1706

This seems to be related to how Moralis is implementing Web3. Any advice would be appreciated!

Note: this is a clean branch. New init of a gatsby site with Moralis and Theme-UI added. All other content and configs have been removed, save for needed polyfills.

Here is the server url: https://memk9nntn6p4.moralis.io:2053/server

My mistake. I misread the docs for Gatsby and was calling the provider in the wrong place. The btoa issue is now resolved, but WalletConnect is not yet working. Will explore it a bit more and come back if I can’t resolve the issue.

Hi @iammatthias,

Looking at your repo, it looks like you have manually added the Walletconnect provider and made it functional in your app.

Could you let us know what error were you facing before the manual addition of the provider? It will help us debug the issue.

Thanks.

Hi @malik,

The error stemmed from misreading the Gatsby docs: https://www.gatsbyjs.com/docs/reference/config-files/gatsby-browser/#wrapRootElement

Allow a plugin to wrap the root element.

This is useful to set up any Provider components that will wrap your application. For setting persistent UI elements around pages use wrapPageElement.

I had initially configured react-moralis to set the provider using the gatsby APIs. After taking a big step back, I realized I had overcomplicated the issue while looking for an answer, and that I just needed to wrap my layout component.

When using the gatsby-browser and gatsby-ssr APIs as described in their docs to load the Moralis provider, it returns the error I included in my initial post.

ERROR 

There was an error compiling the html.js component for the development server.
See our docs page on debugging HTML builds for help https://gatsby.dev/debug-html ReferenceError: btoa is not defined


  21 | }
  22 | else {
> 23 |     _btoa = btoa.bind(window);
     | ^
  24 |     helpers = function (url) {
  25 |         return new URL(url);
  26 |     };


  WebpackError: ReferenceError: btoa is not defined

It looked like this came down from how Moralis had implemented web3-providers-ws, but it was all due to how I had implemented react-moralis.

As of right now, I am able to connect to web3 using WalletConnect with Moralis.


…That said, this has introduced a new bug. At least I think it is a bug?

  1. When reference the walletconnect provider like in the docs I get a No window.ethereum found warning:
import { useMoralis } from 'react-moralis';
import '@walletconnect/web3-provider';

export function GuestbookAuth() {
  const { authenticate, Moralis } = useMoralis();
  //  Create WalletConnect Provider
  return {
    login: async () => {
      Moralis.Web3.getSigningData = () => 'My custom message';
      try {
        await authenticate({
          provider: 'walletconnect',
          onSuccess: () => alert('🎉'),
        });
      } catch (e) {
        console.error(e.message, e);
      }
    },
  };
}

  1. If I manually define and enable the provider, things almost work. It requests to connect, but will only request a signature in browser through MetaMask. In a non-metamask browser it does nothing, and the user is never set.
import { useMoralis } from 'react-moralis';
import WalletConnectProvider from '@walletconnect/web3-provider';

export function GuestbookAuth() {
  const { authenticate, Moralis } = useMoralis();
  //  Create WalletConnect Provider
  const provider = new WalletConnectProvider({
    rpc: {
      1: process.env.GATSBY_MORALIS_NODE,
      4: process.env.GATSBY_MORALIS_NODE_RINKEBY,
    },
  });

  return {
    login: async () => {
      await provider.enable();
      Moralis.Web3.getSigningData = () => 'My custom message';
      try {
        await authenticate({
          provider: provider,
          onSuccess: () => alert('🎉'),
        });
      } catch (e) {
        console.error(e.message, e);
      }
    },
  };
}
  1. Authenticating through MetaMask (no WalletConnect) works as expected—it connects and then requests a signature.

How can I get WalletConnect to request a signature after connecting?

1 Like

Here it is in CodeSandBox.io: https://codesandbox.io/s/async-frost-wfidc

Hi @iammatthias,

We have to yet update our react-moralis with walletconnect integration. Therefore, I would suggest you to use the authenticate functionally directly from the moralis import. Please check out this forum post – WalletConnect provider

I tried using the same code as described in the above forum post and was able to connect and sign a message through a non-metamask browser. I used trustwallet to scan the walletconnect QR code and the signed message also popped up.

Do give it a try and let me know if the issue still persists.

Thank you for your patience. Looking forward to hearing from you. :slight_smile:

Thank you for the context! React-Moralis needing an update clears things up. I’ll give that other method a try.

Is there any ETA on when react-moralis might be updated to support WalletConnect? Might focus on refactoring some other pieces of my project until that is ready.

Looks like it got updated today! I’ll give the new version a try.

1 Like

Everything works locally when running gatsby develop, but when I run gastby build, either locally or through Fleek, the build fails. The btoa bug is back.

iammatthias in net on  master [$] via ⬢ v15.10.0 ➜ gatsby build --prefix-paths --verbose                                                                      37s at 07:09:09 PM •100% 
verbose set gatsby_log_level: "verbose"
verbose set gatsby_executing_command: "build"
verbose loading local command from: /Users/iammatthias/Sites/gatsby/net/node_modules/gatsby/dist/commands/build.js
verbose running command: build

warn Plugin gatsby-plugin-relative-paths is not compatible with your gatsby version 3.9.1 - It requires gatsby@^2.0.0
warn Plugin gatsby-plugin-relative-paths is not compatible with your gatsby version 3.9.1 - It requires gatsby@^2.0.0
success open and validate gatsby-configs, load plugins - 2.203s
success onPreInit - 0.043s
success initialize cache - 0.014s
success copy gatsby files - 0.135s
verbose Attaching functions to development server
success Compiling Gatsby Functions - 0.506s
success onPreBootstrap - 0.520s
success createSchemaCustomization - 0.013s
verbose Fetching default locale
verbose get /: 200 OK (size: 231B request id: f3abba37-e574-4f35-bb36-d5d89b3e5f0b cache: HIT)
verbose get /locales: 200 OK (size: 338B request id: 3de4fb92-be3e-41f0-8afe-964bc3920cd6 cache: HIT)
verbose Default locale is: en-US. There are 1 locales in total.
verbose Contentful: Sync 1000 items per page.
verbose get /sync: 200 OK (size: 324B request id: 37c2d355-a59a-458e-a969-a51b64fb1ecf cache: HIT)
success Contentful: Sync changed items - 0.170s - 0/1000 5891.06/s
verbose get /content_types: 200 OK (size: 1176B request id: e5bbf90a-dea9-4886-a5ff-e43e90fbdf28 cache: HIT)
verbose Content types fetched 6
verbose Default locale: en-US.   All locales: en-US
success Contentful: Fetch data (oisv0rqafzt4-master) - 0.496s
info Updated entries 0
info Deleted entries 0
info Updated assets 0
info Deleted assets 0
verbose Building Contentful reference map
verbose Resolving Contentful references
success Contentful: Process data (oisv0rqafzt4-master) - 0.337s
info Creating 38 Contentful Page nodes
info Creating 73 Contentful Gallery nodes
info Creating 1262 Contentful asset nodes
success Contentful: Create nodes (oisv0rqafzt4-master) - 0.477s
verbose Checking for deleted pages
verbose Deleted 0 pages
verbose Found 0 changed pages
success Checking for changed pages - 0.008s
success source and transform nodes - 1.758s
success building schema - 1.348s
success createPages - 0.144s
success createPagesStatefully - 0.124s
info Total nodes: 1642, SitePage nodes: 42 (use --verbose for breakdown)
verbose Number of node types: 15. Nodes per type: ContentfulAsset: 1262, ContentfulContentType: 6, ContentfulGallery: 73, ContentfulPage: 38, Directory: 1, File: 3, Mdx: 84, Site: 1,
SiteBuildMetadata: 1, SitePage: 41, SitePlugin: 47, ThemeUiConfig: 1, contentfulGalleryMetaDescriptionTextNode: 28, contentfulPageBodyTextNode: 38,
contentfulPageMetaDescriptionTextNode: 18
verbose Checking for deleted pages
verbose Deleted 2 pages
verbose Found 0 changed pages
success Checking for changed pages - 0.011s
success Cleaning up stale page-data - 0.005s
success update schema - 0.104s
success onPreExtractQueries - 0.010s
success extract queries from components - 1.804s
success write out redirect data - 0.007s
success Build manifest and related icons - 0.189s
success onPostBootstrap - 0.195s
info bootstrap finished - 13.837s
success write out requires - 0.005s
success Building production JavaScript and CSS bundles - 38.065s
success Writing page-data.json files to public directory - 0.002s - 0/1 462.66/s
success Building HTML renderer - 7.483s
failed Building static HTML for pages - 1.143s

 ERROR #95313 

Building static HTML failed

See our docs page for more info on this error: https://gatsby.dev/debug-html


  21 | }
  22 | else {
> 23 |     _btoa = btoa.bind(window);
     | ^
  24 |     helpers = function (url) {
  25 |         return new URL(url);
  26 |     };


  WebpackError: ReferenceError: btoa is not defined
  
  - helpers.js:23 
    [i-am-matthias]/[web3-providers-ws]/lib/helpers.js:23:1
  
  - bootstrap:19 
    i-am-matthias/webpack/bootstrap:19:1
  
  - index.js:24 
    [i-am-matthias]/[web3-providers-ws]/lib/index.js:24:15
  
  - bootstrap:19 
    i-am-matthias/webpack/bootstrap:19:1
  
  - index.js:45 
    [i-am-matthias]/[web3-core-requestmanager]/lib/index.js:45:24
  
  - bootstrap:19 
    i-am-matthias/webpack/bootstrap:19:1
  
  - index.js:22 
    [i-am-matthias]/[web3-core]/lib/index.js:22:24
  
  - bootstrap:19 
    i-am-matthias/webpack/bootstrap:19:1
  
  - index.js:29 
    [i-am-matthias]/[web3]/lib/index.js:29:12
  
  - bootstrap:19 
    i-am-matthias/webpack/bootstrap:19:1
  
  - MoralisWeb3.js:35 
    [i-am-matthias]/[moralis]/lib/browser/MoralisWeb3.js:35:35
  
  - bootstrap:19 
    i-am-matthias/webpack/bootstrap:19:1
  
  - ParseUser.js:51 
    [i-am-matthias]/[moralis]/lib/browser/ParseUser.js:51:42
  
  - bootstrap:19 
    i-am-matthias/webpack/bootstrap:19:1
  
  - ParseACL.js:25 
    [i-am-matthias]/[moralis]/lib/browser/ParseACL.js:25:41
  
  - bootstrap:19 
    i-am-matthias/webpack/bootstrap:19:1
  

not finished Caching JavaScript and CSS webpack compilation - 9.474s
not finished Caching HTML renderer compilation - 1.382s

At a loss here, not sure what needs to be changed to make this work in production.

If I run gatsby develop with their FAST_DEV flag set to true it complies, and then gives this error in browser:

Failed to Server Render (SSR)

Error message:

btoa is not defined

File:

node_modules/web3-providers-ws/lib/helpers.js:23:1

Stack:

ReferenceError: btoa is not defined
    at Object../node_modules/web3-providers-ws/lib/helpers.js (/Users/iammatthias/Sites/gatsby/net/public/webpack:/iammatthias/node_modules/web3-providers-ws/lib/helpers.js:23:1)
    at __webpack_require__ (/Users/iammatthias/Sites/gatsby/net/public/webpack:/iammatthias/webpack/bootstrap:19:1)
    at Object../node_modules/web3-providers-ws/lib/index.js (/Users/iammatthias/Sites/gatsby/net/public/webpack:/iammatthias/node_modules/web3-providers-ws/lib/index.js:24:15)
    at __webpack_require__ (/Users/iammatthias/Sites/gatsby/net/public/webpack:/iammatthias/webpack/bootstrap:19:1)
    at Object../node_modules/web3-core-requestmanager/lib/index.js (/Users/iammatthias/Sites/gatsby/net/public/webpack:/iammatthias/node_modules/web3-core-requestmanager/lib/index.js:45:24)
    at __webpack_require__ (/Users/iammatthias/Sites/gatsby/net/public/webpack:/iammatthias/webpack/bootstrap:19:1)
    at Object../node_modules/web3-core/lib/index.js (/Users/iammatthias/Sites/gatsby/net/public/webpack:/iammatthias/node_modules/web3-core/lib/index.js:22:24)
    at __webpack_require__ (/Users/iammatthias/Sites/gatsby/net/public/webpack:/iammatthias/webpack/bootstrap:19:1)
    at Object../node_modules/web3/lib/index.js (/Users/iammatthias/Sites/gatsby/net/public/webpack:/iammatthias/node_modules/web3/lib/index.js:29:12)
    at __webpack_require__ (/Users/iammatthias/Sites/gatsby/net/public/webpack:/iammatthias/webpack/bootstrap:19:1)

I noticed that refreshing the page in my browser shows another error in the terminal:

success building schema - 1.431s
success createPages - 0.088s
info Total nodes: 1643, SitePage nodes: 42 (use --verbose for breakdown)
success Checking for changed pages - 0.002s
success update schema - 0.106s
success onPreExtractQueries - 0.008s
success extract queries from components - 0.401s
success write out requires - 0.003s
success write out requires - 0.001s
success Re-building development bundle - 0.984s
success Writing page-data.json files to public directory - 0.060s - 0/0 0.00/s
warn The path "/" errored during SSR.
Edit its component node_modules/web3-providers-ws/lib/helpers.js:22:1 to resolve the error.

 ERROR #11616 

There was an error while trying to create the client-only shell for displaying SSR errors:
btoa is not defined

File: node_modules/web3-providers-ws/lib/helpers.js:22:1

Adding a polyfill for process has fixed things in development.

exports.onCreateWebpackConfig = ({ actions, stage, plugins }) => {
  if (stage === 'build-javascript' || stage === 'develop') {
    actions.setWebpackConfig({
      plugins: [
        plugins.provide({ process: 'process/browser' })
      ]
    })
  }
}

Attempting a new build, will see how it goes.

2 Likes

Hey @iammatthias Did you manage to fix the build issue? I am getting the exact same btoa error when I build but not when I am in development mode.

The process polyfill solved the issue on Gatsby at the time.

Just curious if you managed to solve the build issue?

My development server works just fine, but when I try to build I get

Node/SSR could not render static page with path "/welcome" because of following error:

ReferenceError: btoa is not defined

maybe you can add this somewhere in the code (not sure if it really helps):

const btoa = function(str){ return Buffer.from(str).toString('base64'); }

I am building the project using webpack, but am not very experienced using it. Any pointers on where this could go in my webpack config make it work server side?

When I add it I see a new error:

Node/SSR could not render static page with path "/welcome" because of following error:

ReferenceError: window is not defined

I am using other webpack plugins to make it work in the browser, making me think that the Buffer that is available is meant for the browser

        plugins: [
          new webpack.ProvidePlugin({
            Buffer: [require.resolve('buffer') , 'Buffer'],
            process: 'process/browser',
          }),
          new webpack.IgnorePlugin({
            resourceRegExp: /^electron$/
          }),
        ],

I don’t have too much experience with webpack either. I just used that btoa function in cloud functions and that is where from I know about it.