Skip to main content

1. Provider setup

import { createRouter, RouterProvider } from '@tanstack/react-router'
import { DeploymentProvider } from '@wacht/tanstack-router'
import { routeTree } from './routeTree.gen'

const router = createRouter({ routeTree })

export function App() {
  return (
    <DeploymentProvider publicKey={import.meta.env.VITE_WACHT_PUBLISHABLE_KEY}>
      <RouterProvider router={router} />
    </DeploymentProvider>
  )
}

2. Server auth in loader/function

import { authenticateRequest } from '@wacht/tanstack-router/server'

export async function getDashboardData(request: Request) {
  const { auth, headers } = await authenticateRequest(request, {
    publishableKey: process.env.WACHT_PUBLISHABLE_KEY,
  })

  if (!auth.userId) {
    return new Response(null, {
      status: 302,
      headers: {
        ...Object.fromEntries(headers.entries()),
        Location: '/sign-in',
      },
    })
  }

  return Response.json({ userId: auth.userId }, { headers })
}

Header propagation contract

authenticateRequest() may rotate/exchange session state and returns response headers (Set-Cookie, auth transport headers).
const { auth, headers } = await authenticateRequest(request, options)
return Response.json(payload, { headers })

getAuth vs requireAuth

  • getAuth: read auth state
  • requireAuth: enforce authentication via protect()