React Forum
Blog & Guide Responses
Jan 21, 2023 · 04:00 PM

[Guide] Build an Auth Flow (Client-Side Checks First) - implementation notes

Started by Camille Duarte
guideauthclient-side checks firstredirect ledgercreateStateVaultuseRenderFetchroute contractsevidence

The Auth Flow guide is very explicit about treating redirects as normal navigation: planned, recorded, and rendered as evidence. It also pushes a route-first check posture (no scattered leaf guards) and a durable auth vault for session truth that can move across file routes and component routes without being re-derived.

Read the guide

How did you model the redirect ledger so it stayed readable (not just a log dump), and what did you render as evidence? Did "client-side checks first" reduce guard sprawl for you, or did you still need leaf checks for edge cases? How did you handle returnTo and provider hints (URL as hint vs route doc as truth) without creating security footguns? What did you store as derived session evidence (source/version/status) so screenshots were actionable?

Comments (18)

Back to latest
Marisol Vega
Jan 25, 2023 · 09:19 AM

The redirect ledger is the best idea in the guide.

Once redirects are recorded, "why did it bounce me" becomes answerable.

Dmitri Kline
Feb 03, 2023 · 10:02 PM

We kept the ledger minimal: only record entries when you cross a file-route boundary or change auth status.

ts
type Entry = { from: string; to: string; reason: string; at: number };

function record(authVault: any, e: Entry) {
  const next = [...authVault.read('ledger'), e].slice(-20);
  authVault.write('ledger', next);
  authVault.write('lastRedirectReason', e.reason);
}

Then the shell renders data-auth-reason and screenshots become meaningful.

Keira Santos
Feb 18, 2023 · 06:30 AM

Counterpoint: client-side checks first can create a false sense of safety if people forget server enforcement.

We had to be explicit in docs that the goal is a stable routing story, not security guarantees.

Camille Duarte
Feb 21, 2023 · 11:40 AM

Agree. The guide's framing helped us: it's about UX + debuggability first, with a clear posture.

We still enforce access server-side; the client check just keeps the route story coherent.

Grace McCoy
Mar 05, 2023 · 04:44 AM

We rendered a small auth evidence line in the shell: status, source, returnTo (sanitized).

It made support debugging much easier without exposing tokens.

Jasper Nguyen
Mar 22, 2023 · 05:17 PM

We treated returnTo as URL hint only and wrote the winning value into the route doc as evidence (returnToSource=hint|local).

Then we allowlist paths in the shell so you can't redirect to arbitrary origins.

Nina Kapoor
Apr 10, 2023 · 08:08 AM

We ended up with a single gate component at the /app entry that self-corrects in render.

If not authenticated, it records the redirect and jumps to login. No scattered checks.

Owen Price
Apr 29, 2023 · 07:01 PM

A misunderstanding I had: I thought the callback route should immediately "finish" auth before rendering anything.

The guide treats it like a normal route that writes session keys and renders evidence as it goes.

Benji Rios
May 18, 2023 · 03:33 AM

We stored derived session.debug.source (hint|callback|local) and it paid off in every bug report.

You can instantly tell if the session came from a callback or from a cached local token.

Lina Ortega
Jun 03, 2023 · 01:37 PM

Docs tie-in: this is routing + safety docs combined.

Related: Routing and Navigation and Security and Safety.

Amina Farouk
Jun 21, 2023 · 06:06 AM

We made the login form a route document with derived canSubmit and status lanes like the guide suggests.

It made submit behavior consistent and prevented double-submits.

Tomas Rivera
Jul 08, 2023 · 10:44 PM

Snippet: a simple gate that records an evidence reason before redirecting:

tsx
function RequireAuth({ children }: { children: React.ReactNode }) {
  const auth = useVaultMirror('auth');
  const jump = useRouteJump();
  if (auth.read('session').status !== 'authenticated') {
    auth.write('ledger', [...auth.read('ledger'), { from: '/app', to: '/auth/login', reason: 'anonymous', at: Date.now() }]);
    jump.to('/auth/login');
    return null;
  }
  return <>{children}</>;
}
Sofia Valdez
Jul 30, 2023 · 05:05 AM

Counterpoint: recording ledgers in a vault can leak sensitive info if you aren't careful about what you store.

We kept reasons generic and never store tokens/emails in the ledger.

Grace McCoy
Aug 02, 2023 · 09:12 PM

Same. We treat the ledger like security logs: only store what you can safely ship to clients.

The evidence should explain motion, not contain secrets.

Theo Bennett
Aug 18, 2023 · 02:40 PM

Provider hints were easiest when they only set the initial mode, and the route doc becomes truth immediately.

If the URL keeps winning forever, the login screen feels inconsistent.

Evan Brooks
Sep 09, 2023 · 02:20 AM

We shipped a debug-only panel that shows the last ledger entry and session lane.

It made auth bugs feel like normal bugs instead of "auth is cursed".

Imani Brooks
Oct 01, 2023 · 10:10 AM

The "route story first" planning section is worth copying into internal docs.

If you plan the map and the evidence keys, implementation decisions get a lot simpler.

Salma Qureshi
Oct 28, 2023 · 04:16 PM

I liked that logout is treated as a normal route transition with evidence.

It keeps auth behavior from being a special case that nobody can test reliably.

Rowan Pierce
Nov 20, 2023 · 09:05 PM

We had an edge case where returnTo pointed at a route that no longer exists.

The guide's posture of self-correcting navigation in render made it easy to handle (bounce to /app and record reason).

Jules Kwon
Dec 11, 2023 · 03:03 AM

Auth flows got calmer once redirects were treated as first-class state transitions with evidence, not mysterious side effects.