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.
- Auth0 won’t append
- 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
_redirectsfile 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.


