Using Auth0 Redirects with Vue.js Hash Routing and a Path-Based Callback

Introduction

When building single-page applications (SPAs) with Vue.js, many developers choose hash mode routing (#/dashboard) because it simplifies server configuration. However, when integrating with Auth0, redirects with query parameters (?code=...&state=...) don’t work well with hash-based routes like /#/callback.

The good news? You can keep your entire SPA hash-based, while still using a path-based callback route (/auth/callback) for Auth0 redirects. This gives you clean URLs, reliable OAuth handling, and no server headaches.

Why the Problem Exists?

  • Hash routes are never sent to the server. For example: https://example.com/#/callback
    • Auth0 won’t append ?code=...&state=... after the hash.
  • OAuth redirects require query parameters to complete login.
  • Therefore, we need a real path-based callback where Auth0 can deliver those parameters.

Step 1: Configure Auth0

In your Auth0 Dashboard → Application Settings, add the following to Allowed Callback URLs:

https://yourapp.com/auth/callback

Step 2: Initialize Auth0 in Vue

In your app setup:

import { createAuth0 } from "@auth0/auth0-vue";

app.use(
  createAuth0({
    domain: "your-tenant.auth0.com",
    clientId: "yourClientId",
    authorizationParams: {
      redirect_uri: window.location.origin + "/auth/callback",
    },
  })
);

Step 3: Add a Path-Based Callback Route

Even if your app is fully hash-routed, define a dedicated route for /auth/callback:

const routes = [
  {
    path: '/auth/callback',
    component: () => import('./pages/CallbackPage.vue'),
  },
  {
    path: '/:catchAll(.*)',
    component: () => import('./pages/AppRoot.vue'), // your normal SPA
  }
];

Step 4: Handle Redirects in CallbackPage

Your CallbackPage.vue can look like this:





<script setup>
import { useAuth0 } from "@auth0/auth0-vue";
import { onMounted } from "vue";
import { useRouter } from "vue-router";

const { handleRedirectCallback } = useAuth0();
const router = useRouter();

onMounted(async () => {
  await handleRedirectCallback();
  router.replace('/#/dashboard'); // Jump back into hash routing
});
</script>

<template>
  <div>Signing you in...</div>
</template>

Step 5: Ensure Server Serves index.html

Your hosting must return index.html for /auth/callback, so Vue can boot and handle the route. For example:

  • Netlify → Add a _redirects file with /* /index.html 200.
  • Nginx/Apache → Use a catch-all rewrite to index.html.

Conclusion

By combining a path-based callback (/auth/callback) with hash-based routing (#/dashboard), you get the best of both worlds:

  • A clean, reliable redirect flow for Auth0.
  • A hash-based SPA that doesn’t require complex server rewrites.

This approach works well in production environments where OAuth compatibility and SPA simplicity are equally important.

Author: Danyal
I'm a skilled programmer specializing in Vue.js/Nuxt.js for front-end development and PHP Laravel for back-end solutions. I have a strong focus on API design and development, complemented by experience in web server setup and maintenance. My versatile expertise ensures seamless creation and maintenance of web applications, covering everything from intuitive user interfaces to robust server-side functionality. Passionate about coding and driven by a lifelong learning mindset, I invite you to explore more at danyal.dk.