Auth0.js: Import fails on node.js because window is not defined

Created on 2 Jul 2019  路  20Comments  路  Source: auth0/auth0.js

Description

import auth0 from "auth0-js"; causes an exception on nodejs

Prerequisites

Environment

Please provide the following:

  • Version of Auth0.js used: 9.11.1
  • Browser and OS version(s) affected: Any nodejs
  • Additional libraries or browser extensions being used that might affect behavior: N/A

Reproduction

$ yarn add auth0-js
$ node
> const auth0 = require("auth0-js");

Output:

Thrown:
ReferenceError: window is not defined

Most helpful comment

I had a nice conversation with @timneutkens and @developit and they helped me finding a solution for this. We'll fix this in the next release: https://github.com/auth0/idtoken-verifier/pull/42

Thanks for your patience 馃帀

All 20 comments

This library is not meant to be used in nodejs. Checkout https://github.com/auth0/node-auth0

@luisrudge I appreciate that, but we are trying to use this library in a server rendered React app. While we load this library on the server, none of the functions which rely on browser functionality are called. Is there a way you could just make it possible to import the library on the server, similar to how 9.10.x works?

When the lib is initialized, it checks to see if localStorage is available or not, that's why we need the window object. Normally, when you're SSRing your app (like using Next.js, for example), you're better off avoiding using Auth0.js altogether. We have a great write up on this here: https://auth0.com/blog/next-js-authentication-tutorial/

Thanks, I'll have a read of that

I think this is an issue with auth0-js.

First of all, this problem has been recently introduced, since 9.10.4 works great, 9.11.x causes my builds to break. When using ^9.10.4, 9.11.x will be installed automatically. So if no lock file used, builds will break.

Second, it really is not hard to check for window to exist (typeof window !== 'undefined').

Third, there is valid reasons to use auth0-js in server rendered apps. Cases where you may for example show a placeholder in your sidebar and then, on client side, if user is logged in, render the avatar image. The whole stuff that is user specific can easily be lazy loaded on the client side after initial render.

Agreed. At the very least this should have been a major version bump

Can you give me a stack trace on where the error is happening?

@luisrudge I can't give a helpful stacktrace as everything is minified, but the error is originating in the unfetch package.

My guess is that you're packaging isomorphic-unfetch along with idtoken-verifier, which means only the web version will be included in the final bundle. The package itself isn't actually isomorphic, it just loads the correct version based on whether or not webpack is set to node or web using the package.json file

https://github.com/developit/unfetch/blob/master/packages/isomorphic-unfetch/package.json

I think isomorphic-unfetch is doing what it is supposed to do, as are we. This is a browser-only library, so it makes sense to package the library as we do. If you're SSRing your app, you need to make sure that you're loading our library only in the client side. For example, Next.js has a way to disable SSR for dynamic imports: https://github.com/zeit/next.js#with-no-ssr.

NextJS has dynamic imports, but these are (in nextjs context) meant for component rendering, not for utility libraries.

I would really expect a library like auth0-js to work without throwing exceptions if imported. I totally get we can't actually use auth0-js on the server (which auth0-node is for). There is many solutions, like modifying next.config.js/webpack config to alias auth0-js to some noop library server side or whatever. But if I had to do such efforts for each of the libraries I'm using through my apps, I'd be writing a lot of config code.

I'm still considering this a bug since previous versions worked without throwing, and as I said, the reason I came aware of this issue was failing builds (on my CI environment), so now I (and I'm sure others, lets wait and see) will have to invest time fixing this by doing stuff like:

let auth0;
if (typeof window !== 'undefined')聽{
auth0 = require('auth0-js');
}

The wonderful typescript bindings, of course, will not work now. But well, at least no exception.

Here a reproduction btw:
https://github.com/bkniffler/auth0-bug

I had a nice conversation with @timneutkens and @developit and they helped me finding a solution for this. We'll fix this in the next release: https://github.com/auth0/idtoken-verifier/pull/42

Thanks for your patience 馃帀

I'm still having this issue.

auth0-js v.9.11.1 is not updating its idtoken-verifier dependency to v.1.4.1 in yarn.lock

I'm using Yarn and have not been able to selectively update the dependency. This seems to be a known bug (https://github.com/yarnpkg/yarn/issues/4986) with several workarounds, but none of them have worked for me.

I'm still getting the "window is not defined error." Any ideas?

We鈥檒l release a new version on Monday.

Why is this issue closed without resolution? We ran into the same problem on what was expected to be just a minor version bump with no breaking changes. Our web app is also an isomorphic react app.

@dgilling there was no breaking changes for our supported scenarios. As said in https://github.com/auth0/auth0.js/issues/959#issuecomment-511030335, we'll release a fix for this next Monday.

@luisrudge Can you consider making Isomorphic React apps a supported scenario? It's one of the most popular front end frameworks used by startups to companies like Walmart. I am surprised Auth0 doesn't consider this a common scenario and doesn't have regression testing for it.

I even see a blog post here: https://auth0.com/blog/bootstrapping-a-react-project/

It is common, but using auth0.js inside nodejs is not supported (which is what an SSR app does when it's rendering in the server), so it makes sense to keep repeating this scenario is not supported. Of course, we want to support your client side part of the app as good as we possible can and we're committed to that. This will be fixed in the next release, which will be out next week.

Hi everyone. This was fixed in the latest version. Thanks for your patience 馃帀

import { useEffect } from "react";
import { WebAuth } from "auth0-js";

function Home() {
  useEffect(() => {
    const auth = new WebAuth({
      domain: "test.auth0.com",
      clientID: "alsdhalskhd02h0"
    });
  }, []);
  return <div>Welcome to Next.js!</div>;
}

export default Home;

Working now. Thanks!!

Was this page helpful?
0 / 5 - 0 ratings