React Router
The example setup is live here: https://example-react-router.oidc-spa.dev/
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
This is for setting for integrating oidc-spa with react-router in Framework Mode
.
Enabling SPA mode
As of today, to use oidc-spa you need to enable SPA mode.
import type { Config } from "@react-router/dev/config";
export default {
ssr: false
} satisfies Config;
(Optional) Improve dev mode by pre-optimizing dependencies
In dev mode, listing your dependencies in optimizeDeps.include
can prevent annoying glitches that forces you to reload your page manually.
import { reactRouter } from "@react-router/dev/vite";
import { defineConfig } from "vite";
export default defineConfig({
plugins: [reactRouter()],
optimizeDeps: {
include: [
"oidc-spa/react",
"oidc-spa/entrypoint",
"oidc-spa/tools/parseKeycloakIssuerUri",
"oidc-spa/tools/decodeJwt",
"zod"
]
}
});
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:
Protecting pages and using the Page Loaders
Let's say we have an invoice page and you want this page to be accessible only when the user is logged in. You also want to fetch the API to get the invoces of the user. This is how you would implement it:
import { enforceLogin, fetchWithAuth } from "../oidc.client";
import type { Route } from "./+types/invoices";
import { useLoaderData } from "react-router";
export async function clientLoader(params: Route.ClientLoaderArgs) {
// If you have `autoLogin: true` this isn't nessesary.
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
The example setup is live here: https://example-react-router-framework.oidc-spa.dev/
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
Last updated
Was this helpful?