Skip to content

Add Clerk session keepalive to all authenticated pages #17

Description

@unforced

Context

PR #6 identified that Clerk session JWTs expire after ~60s. Pages that don't load the Clerk SDK have nothing to refresh the token in the background, so if a user lingers on an authenticated page and then submits a form (or clicks an authenticated link), the backend middleware rejects the expired JWT and silently redirects to /sign-in/auth/callback/dashboard. Their action is lost.

PR #6 fixed this for admin pages via clerkPubKey={c.env.CLERK_PUBLISHABLE_KEY} on the Layout. Just shipped the same fix for settings, projects, and discussions routes (where users spend time typing).

Still missing coverage

Every Layout call on these routes needs the same prop:

  • src/routes/community.tsx (2)
  • src/routes/members.tsx (3)
  • src/routes/feedback.tsx (2)
  • src/routes/cohort.tsx (6)
  • src/routes/payment.tsx (10 — but many are pre-auth, needs thought)
  • src/routes/pages.tsx (6 — /apply and /apply/status in particular)

Proposed fix

Instead of adding the prop at every call site (and forgetting on new routes), thread CLERK_PUBLISHABLE_KEY through middleware into a context that Layout can read, or default to always loading the Clerk SDK when user is non-null.

Option A: Add clerkPubKey explicitly to each remaining Layout call. Boring but obvious.

Option B: In middleware, c.set('clerkPubKey', c.env.CLERK_PUBLISHABLE_KEY). Have Layout take an optional c context or read a global. Less boilerplate, more indirection.

Option C: When user is present in Layout and clerkPubKey is not passed, render a console warning in dev so it's visible. Keeps explicit pattern but makes omissions loud.

My vote: A for now, C later. It's 30 Layout calls — boring but local and grep-able. Adding indirection via context/env propagation is over-engineered for the current size.

Verify

After fixing, load /settings/profile, wait 2 minutes, submit the form, and confirm it saves. Before the fix this silently loses the save.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions