TanStack Start

TanStack Start integration uses createServerFn to run auth refresh on the server and pass the token to the client.

Server function

Create a server function that calls auth.refresh() with the incoming request. Use getRequest() to access the raw request and setCookie() to apply auth cookies to the response.

// app/auth.server.ts
import { server } from "@robelest/convex-auth/server";
import { createServerFn } from "@tanstack/start";
import { getRequest, setCookie } from "@tanstack/start/server";

const auth = server({ url: process.env.CONVEX_URL! });

export const getAuthToken = createServerFn("GET", async () => {
  const request = getRequest();
  const { cookies, redirect, token } = await auth.refresh(request);

  // Apply auth cookies
  for (const cookie of cookies) {
    setCookie(cookie.name, cookie.value, {
      path: cookie.path ?? "/",
      httpOnly: cookie.httpOnly,
      secure: cookie.secure,
      sameSite: cookie.sameSite as "lax" | "strict" | "none",
      maxAge: cookie.maxAge,
    });
  }

  // Return redirect URL or token
  if (redirect) {
    return { redirect };
  }

  return { token };
});

Using in a route

Call the server function from a loader to make the token available during SSR:

// app/routes/index.tsx
import { createFileRoute, redirect } from "@tanstack/react-router";
import { getAuthToken } from "../auth.server";

export const Route = createFileRoute("/")({
  beforeLoad: async () => {
    const result = await getAuthToken();

    if ("redirect" in result && result.redirect) {
      throw redirect({ href: result.redirect });
    }

    return { token: result.token };
  },
});

Auth proxy

For client-side sign-in/sign-out, create a server function that proxies to Convex:

// app/authProxy.server.ts
import { server } from "@robelest/convex-auth/server";
import { createServerFn } from "@tanstack/start";
import { getRequest } from "@tanstack/start/server";

const auth = server({ url: process.env.CONVEX_URL! });

export const authProxy = createServerFn("POST", async () => {
  const request = getRequest();
  return auth.proxy(request);
});