#TanStack Router + Better Auth Setup

5 messages · Page 1 of 1 (latest)

gusty rain
#

hi, i'm setting convex better auth up in a tanstack router vite app. i primarily followed the start docs and only deviated away towards the react docs whenever i couldn't do something server related. for those moments, i mostly guessed so i was hoping someone could proof-read my implementation and see if i'm missing something lol. not using start because i don't need ssr btw. thanks :)

faint flumeBOT
#

Thanks for posting in #1088161997662724167.
Reminder: If you have a Convex Pro account, use the Convex Dashboard to file support tickets.

    - Provide context: What are you trying to achieve, what is the end-user interaction, what are you seeing? (full error message, command output, etc.)
    - Use [search.convex.dev](https://search.convex.dev) to search Docs, Stack, and Discord all at once.
    - Additionally, you can post your questions in the Convex Community's #1228095053885476985 channel to receive a response from AI.
    - Avoid tagging staff unless specifically instructed.

    Thank you!
gusty rain
#
// main.tsx
const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL, {
    expectAuth: true,
    unsavedChangesWarning: false,
});

const convexQueryClient = new ConvexQueryClient(convex);

const queryClient = new QueryClient({
    defaultOptions: {
        queries: {
            queryKeyHashFn: convexQueryClient.hashFn(),
            queryFn: convexQueryClient.queryFn(),
        },
    },
});

convexQueryClient.connect(queryClient);

const router = createRouter({
    routeTree,
    context: {
        queryClient,
        convexClient: convex,
        convexQueryClient,
    },
    defaultPreload: "intent",
    // Since we're using React Query, we don't want loader calls to ever be stale
    // This will ensure that the loader is always called when the route is preloaded or visited
    defaultPreloadStaleTime: 0,
    scrollRestoration: true,
});

declare module "@tanstack/react-router" {
    interface Register {
        router: typeof router;
    }
}

const root = document.getElementById("root");
if (!root) throw new Error("Failed to find the root element");

createRoot(root).render(
    <StrictMode>
        <ConvexBetterAuthProvider client={convex} authClient={auth}>
            <RouterProvider router={router} />
        </ConvexBetterAuthProvider>
    </StrictMode>,
);
#
// routes/__root.tsx
export const Route = createRootRouteWithContext<{
    queryClient: QueryClient;
    convexClient: ConvexReactClient;
    convexQueryClient: ConvexQueryClient;
}>()({
    component: RootComponent,
});

function RootComponent() {
    return <Outlet />;
}
#
// routes/index.tsx
export const Route = createFileRoute("/")({
    component: RouteComponent,
});

function RouteComponent() {
    return (
        <>
            <Unauthenticated>
                <p>Sign in form</p>
            </Unauthenticated>

      {/* This lives in a pathless layout route _authenticated */}
            <Authenticated>
                <Navigate to="/authenticated-route" />
            </Authenticated>
        </>
    );
}