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. SDK reference: TanStack Start.
The incident list answers who the operator is. It does not grant a permission. Apply authorization before you treat a row as something that operator may change.
What you need
| Requirement | Detail |
|---|---|
| Public key | pk_... from the console |
| 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
npm install
npm run devOpen 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.
// 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.
// 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.