Altryne
Altryne

Reputation: 471

Auth0 authentication with Gridsome server side rendering breaks with window is undefined

I've implemented the auth0 Vuejs according to their tutorial with Gridsome, and it worked fine in develop. However, when I run gridsome build the build fails because window is undefined in a server context.

I've found a few issues in Auth0-js lib that claim that Auth0 should only be used in client side, however, due to the way Gridsome works, I can't seem to find a way to only load the Auth0-js in client side.

Gridsome has main.js where I would add plugins, and in there, I define the routing for authentication.

Main.js

import AuthServicePlugin from '~/plugins/auth0.plugin'
import auth from '~/auth/auth.service'

export default function (Vue, { router, head, isClient }) {
  ...
  Vue.use(AuthServicePlugin)
  //Handle Authentication
  router.beforeEach((to, from, next) => {
    if (to.path === "/auth/logout" || to.path === "/auth/callback" || auth.isAuthenticated()) {
      return next();
    }

    // Specify the current path as the customState parameter, meaning it
    // will be returned to the application after auth
      auth.login({ target: to.path });

  })

Based on a Gatsbyb.js auth0 implementation tutorial, I've tried to exlude auth0-js from webpack loading with null-loader

gridsome.config.js

configureWebpack: {
    /*
     * During the build step, `auth0-js` will break because it relies on
     * browser-specific APIs. Fortunately, we don’t need it during the build.
     * Using Webpack’s null loader, we’re able to effectively ignore `auth0-js`
     * during the build. (See `src/utils/auth.js` to see how we prevent this
     * from breaking the app.)
    */
    module: {
      rules: [
        {
          test: /auth0-js/,
          use: 'null-loader',
        },
      ],
    },

I would love to get some ideas about how to include and load Auth0 only in client side context with Gridsome

Upvotes: 4

Views: 1160

Answers (1)

yiddishe-kop
yiddishe-kop

Reputation: 508

I had the same problem with using Firebase Authentication with Gridsome.

It seems that code in the created() lifecycle hook gets executed in the Gridsome build process (which is a server environment), but code in the mounted() lifecycle hook only executes in the browser!

The solution was to put all the code that should only run in the client in the mounted lifecycle hook.

mounted() {
  // load the `auth0-js` here
  ...
}

In my instance (with Firebase Auth) this was the solution:

In the Default Layout component:

const app = import("firebase/app");
    const auth = import("firebase/auth");
    const database = import("firebase/firestore");
    const storage = import("firebase/storage");

    Promise.all([app, auth, database, storage]).then(values => {
      // now we can access the loaded libraries 😍!
    });
}

Upvotes: 2

Related Questions