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 1 month 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