The ops console lists open incidents after hosted sign-in. Anonymous visitors see the sign-in link and no incident rows.

Clone [starters/tanstack-start](https://github.com/authdog/samples/tree/main/starters/tanstack-start). SDK reference: [TanStack Start](/docs/frameworks/tanstack-start).

The incident list answers who the operator is. It does not grant a permission. Apply [authorization](/docs/concepts/authorization) before you treat a row as something that operator may change.

## What you need

| Requirement | Detail |
| --- | --- |
| Public key | `pk_...` from the [console](https://console.authdog.com) |
| Environment | Copy `.env.example` to `.env` and set `PK_AUTHDOG` |
| Secret key | Never put `sk_...` in client code |
| Return URL | Account portal back to this app. Local: `http://localhost:3000` |

## Run

```bash
npm install
npm run dev
```

Open http://localhost:3000. Sign in through the hosted Account portal. The home page shows `Signed in as` plus the open incidents (`inc_204` Checkout, `inc_205` Search). `/api/logout` clears the cookies.

## Incidents

The home route reads identity from the root loader. `isAuthenticated` decides whether the on-call list renders.

```tsx
// src/routes/index.tsx
const INCIDENTS = [
  { id: "inc_204", service: "Checkout", severity: "sev-2", state: "mitigating" },
  { id: "inc_205", service: "Search", severity: "sev-3", state: "monitoring" },
]

function Home() {
  const { identity } = Route.useRouteContext()
  if (!identity?.isAuthenticated) {
    return <a href={identity?.signinUri}>Sign in with the hosted Account portal</a>
  }
  return (
    <ul>
      {INCIDENTS.map((incident) => (
        <li key={incident.id}>
          {incident.id} · {incident.service} · {incident.severity} · {incident.state}
        </li>
      ))}
    </ul>
  )
}
```

## Session

`identityLoader` exchanges the callback and resolves identity. `AuthdogProvider` only strips `?token=` and reloads. It does not validate, persist, or guard. Return the loader `Response` unchanged when you need its `Set-Cookie` headers. Calling `.json()` and rebuilding the response drops them.

```tsx
// src/routes/__root.tsx
import { createRootRoute, Outlet } from "@tanstack/react-router"
import { createServerFn } from "@tanstack/react-start"
import { identityLoader } from "@authdog/tanstack-start"
import { AuthdogProvider } from "@authdog/tanstack-start/client"

const loadIdentity = identityLoader()

const getIdentity = createServerFn({ method: "GET" }).handler(async () => {
  const request = (await import("@tanstack/react-start/server")).getRequest()
  const response = await loadIdentity({ request })
  return response.json()
})

export const Route = createRootRoute({
  loader: () => getIdentity(),
  component: RootComponent,
})

function RootComponent() {
  const identity = Route.useLoaderData()
  return (
    <AuthdogProvider>
      <Outlet context={{ identity }} />
    </AuthdogProvider>
  )
}
```

The loader reports `isAuthenticated`. The home route enforces that flag before it renders incidents.
