OIDC SPA
GitHubHome
v6
  • Documentation
  • Release Notes & Upgrade Instructions
v6
  • Installation
  • Basic Usage
  • Web API
  • Auto Login
  • Auto Logout
  • Error Management
  • Mock
  • User Account Management
  • User Session Initialization
  • Tokens Renewal
  • Setup Guides
    • React Router
    • TanStack Router
    • Full-Stack with Node REST API
  • Providers Configuration
    • Keycloak
    • Auth0
    • Microsoft Entra ID
    • Google OAuth 2.0
    • Other OIDC Provider
  • Resources
    • Why No Client Secret?
    • End of third-party cookies
    • JWT Of the Access Token
    • Discord Server
  • User Impersonation
  • Sponsors
Powered by GitBook
On this page

Was this helpful?

Export as PDF
  1. Setup Guides

React Router

PreviousTokens RenewalNextTanStack Router

Last updated 15 days ago

Was this helpful?

The example setup is live here:

Run it locally with:

npx degit https://github.com/keycloakify/oidc-spa/examples/react-router oidc-spa-react-router
cd oidc-spa-react-router
cp .env.local.sample .env.local
yarn
yarn dev

Enabling SPA mode

react-router.config.ts
import type { Config } from "@react-router/dev/config";

export default {
    // Config options...
    // Server-side render by default, to enable SPA mode set this to `false`
    ssr: false
} satisfies Config;

oidc.client.ts

Make sure you create a app/oidc.client.ts file, (instead of app/oidc.ts).

Setting up the entrypoint

Create thoses two files:

Working with loaders

The default approach when you want to enforce that the user be logged in when accesing a given route is to wrap the component into withLoginEnforced(), example:

pages/invoices.tsx
import { useState, useEffect } from "react";
import { withLoginEnforced, fetchWithAuth } from "../oidc.client";

const Invoices = withLoginEnforced(
    () => {
        const [invoices, setInvoices] = useState<Invoice[] | undefined>(undefined);

        useEffect(() => {
            fetchWithAuth("/api/invoices")
                .then(r => r.json())
                .then(setInvoices);
        }, []);

        if (invoices === undefined) {
            return <div>Loading invoices...</div>;
        }

        return (
            <div>
                {invoices.map(invoice => (
                    <div key={invoice.id}>{invoice.amount}</div>
                ))}
            </div>
        );
    },
    {
        onRedirecting: () => <div>Redirecting to login...</div>
    }
);

export default Invoices;

This approach is framework agnostic and always works however, you might want to use the loaders to doload the data, for that you would use enforceLogin() istead of withLoginEnforced:

pages/invoices.tsx
import { enforceLogin, fetchWithAuth } from "../oidc.client";
import type { Route } from "./+types/invoices";
import { useLoaderData } from "react-router";

export async function clientLoader(params: Route.ClientLoaderArgs) {
    await enforceLogin(params);
    // If we are here, the user is logged in.
    const invoices = await fetchWithAuth("/api/invoices").then(r => r.json());
    return invoices;
}

export function HydrateFallback() {
    return <div>Loading invoices...</div>;
}

export default function Invoices() {
    const invoices = useLoaderData<typeof clientLoader>();

    return (
        <div>
            {invoices.map(invoice => (
                <div key={invoice.id}>{invoice.amount}</div>
            ))}
        </div>
    );
}

Running the example

Run it locally with:

npx degit https://github.com/keycloakify/oidc-spa/examples/react-router-framework oidc-spa-react-router
cd oidc-spa-react-router
cp .env.local.sample .env.local
yarn
yarn dev

This is for setting for integrating oidc-spa with react-router in .

As of today, to use oidc-spa you need to .

If your whole app requires user to be authenticated () you can skip this section.

The example setup is live here:

Framework Mode
enable SPA mode
autoLogin: true
https://example-react-router-framework.oidc-spa.dev/
https://example-react-router.oidc-spa.dev/
https://github.com/keycloakify/oidc-spa/tree/main/examples/react-router
oidc-spa/examples/react-router-framework/app/oidc.client.ts at main · keycloakify/oidc-spaGitHub
Example of oidc.client.ts file
oidc-spa/examples/react-router-framework/app/entry.client.tsx at main · keycloakify/oidc-spaGitHub
app/entry.client.tsx
oidc-spa/examples/react-router-framework/app/entry.client.lazy.tsx at main · keycloakify/oidc-spaGitHub
app/entry.client.lazy.tsx
oidc-spa/examples/react-router-framework at main · keycloakify/oidc-spaGitHub
Logo
Logo
Logo
Logo