Migration from react-oidc-context
This library is a deliberate port of react-oidc-context v3: same thin-wrapper philosophy, same option names, same lifecycle. Migrating is mostly mechanical.
Configuration: copy it unchanged
createOidcAuth() takes exactly the flat shape of AuthProviderProps — UserManagerSettings keys and callbacks side by side:
import { AuthProvider } from "react-oidc-context";
const oidcConfig = {
authority: "https://idp.example.com",
client_id: "spa",
redirect_uri: `${window.location.origin}/`,
onSigninCallback: () => {
window.history.replaceState({}, document.title, window.location.pathname);
},
};
root.render(
<AuthProvider {...oidcConfig}>
<App />
</AuthProvider>,
);import { createOidcAuth } from "@dlukt/vue-oidc-context";
const oidcConfig = {
authority: "https://idp.example.com",
client_id: "spa",
redirect_uri: `${window.location.origin}/`,
onSigninCallback: () => {
window.history.replaceState({}, document.title, window.location.pathname);
},
};
createApp(App).use(createOidcAuth(oidcConfig)).mount("#app");All callbacks keep their names and semantics: onSigninCallback, skipSigninCallback, matchSignoutCallback, onSignoutCallback, onRemoveUser.
API mapping
| react-oidc-context | @dlukt/vue-oidc-context |
|---|---|
<AuthProvider {...oidcConfig}> (app root) | app.use(createOidcAuth(oidcConfig)) — same flat config object |
<AuthProvider> (nested / multi-IdP) | <AuthProvider :settings="…"> component |
const auth = useAuth() | const { user, isAuthenticated, … } = useAuth() — destructure; fields are refs |
auth.isLoading (plain boolean) | isLoading.value in script, isLoading in templates |
withAuthenticationRequired(Component, opts) | createAuthGuard(auth) + meta.requiresAuth, or AuthenticationRequired (component tree) |
withAuth(Component) | not ported — use useAuth() / provider slot props |
useAutoSignin(opts) | useAutoSignin(opts) — identical |
hasAuthParams() | hasAuthParams() — identical |
AuthContext (React context object) | AUTH_CONTEXT_KEY (Vue injection key) |
The one real difference: reactivity
React re-renders with plain values; Vue hands you refs. The state fields (user, isLoading, isAuthenticated, activeNavigator, error) are read-only refs on the context object:
// React
if (auth.isLoading) { ... }
// Vue (script)
const { isLoading } = useAuth();
if (isLoading.value) { ... }In templates, destructured refs unwrap automatically — v-if="isLoading" just works. Two things to keep in mind:
- Don't destructure through the object into plain values once and expect updates (
const loading = useAuth().isLoading.valueis a snapshot). - If you keep the whole context (
const auth = useAuth()), nested refs don't unwrap in templates — writeauth.isLoading.value.
Behavior parity notes
Everything below matches react-oidc-context, so upstream docs, issues, and intuition carry over:
- The initialization sequence (signin-callback processing,
getUser()fallback) and its error handling. - URL cleanup is your job in
onSigninCallback— but in a vue-router app prefervoid router.replace(...)overhistory.replaceState(why). addUserSignedOutkeepsuserbut flipsisAuthenticatedtofalse.isAuthenticatedis not time-reactive: a token expiring does not by itself flip it.- Navigator failures land on
errorand the returned promise still rejects. - Teardown only unsubscribes events — it never calls
stopSilentRenew()or clears storage.