The `@authdog/react-router` SDK provides a loader-based session, a logout loader, and a minimal client provider for React Router 7 in framework mode. Loaders and actions run on the Web Fetch API, so the SDK returns plain `Response` objects and needs no Node adapter.

`@authdog/react-router` is not yet published to npm (`npm view @authdog/react-router` returns 404 at the time of writing). Version `0.1.0` is set to publish publicly from the `web-sdk` repository, so install it from there until it lands on the registry.

## Install

```package-install
@authdog/react-router
```

`react` and `react-dom` (`^18.2` or `^19`) and `react-router` `^7` are peer dependencies. The package ships two entry points: `@authdog/react-router` (server loaders) and `@authdog/react-router/client` (provider). Set `PK_AUTHDOG` to your environment's public key (`pk_...`) in the server environment.

## Read the session in a loader

`identityLoader()` reads `PK_AUTHDOG` and returns a loader. Read its result with `useLoaderData`:

```ts
// app/routes/_index.tsx
import { identityLoader } from "@authdog/react-router"

export const loader = identityLoader()
```

```tsx
import { useLoaderData } from "react-router"

export default function Index() {
  const { user, isAuthenticated, signinUri } = useLoaderData<typeof loader>()
  return isAuthenticated ? <p>Hi {user.displayName}</p> : <a href={signinUri}>Sign in</a>
}
```

The loader returns `{ user, isAuthenticated, signinUri }`, where `signinUri` is the hosted sign-in URL for your environment. Behaviour:

- If the request has a `?token=`, the loader resolves it through the Authdog userinfo endpoint. On success it sets two HttpOnly `Secure` `SameSite=Strict` cookies, `user_session_<envId>` (the user JSON) and `user_session_hash_<envId>` (the token), with no-store cache headers.
- Otherwise it re-validates the session by calling userinfo with the token from `user_session_hash_<envId>`.
- If neither succeeds, it returns `{ user: null, isAuthenticated: false, signinUri }`.

The raw token never reaches client JavaScript. It throws if `PK_AUTHDOG` is missing, malformed, or points at an untrusted identity host. The cookies are `Secure`, so test over HTTPS or on `localhost`.

## Provider

Mount `AuthdogProvider` at the app root. It takes no props besides `children`. When it sees a `?token=` in the URL, it strips the parameter and reloads once so the loader runs:

```tsx
import { AuthdogProvider } from "@authdog/react-router/client"

export default function App() {
  return <AuthdogProvider>{/* ... */}</AuthdogProvider>
}
```

`ReloadPage` is also exported. It strips `?token=` from the URL without reloading.

## Sign out

Export `logoutLoader` from a route. It clears both session cookies and redirects to `/`:

```ts
// app/routes/logout.tsx
import { logoutLoader } from "@authdog/react-router"

export const loader = logoutLoader
```

For local development, `identityDevAction({ redirectTo })` clears the same cookies and redirects to a sanitized `redirectTo` (default `/`). It throws in production.

## Other exports

`reactRouterAuthLoader`, `authenticateWithCookies`, `createAuthResponse`, `jsonResponse`, and `redirectResponse` are exported for custom loaders. Most apps need only `identityLoader`.

## Caveats

- `isAuthenticated` means userinfo accepted the token on that request. Cookie presence alone is not treated as authentication.
- The SDK does not protect routes for you. Check `isAuthenticated` in each loader that needs it, and enforce [authorization](/docs/concepts/authorization) in actions and API routes.
- Verbose `[Authdog]` debug logging is enabled whenever `NODE_ENV` is not `production`.

## Next steps

- [Sign up & sign in](/docs/authentication): the flows behind the redirect.
- [Backend requests](/docs/backend): the verification model, in depth.
