> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bijection.com/llms.txt
> Use this file to discover all available pages before exploring further.

# TanStack Start with Clerk

> Learn how to integrate Clerk authentication with Bijection in TanStack Start applications using ID tokens and BijectionProviderWithClerk.

Using Clerk with Bijection looks like following the
[Clerk TanStack Quickstart](https://clerk.com/docs/quickstarts/tanstack-start)
and adding Bijection like the
[Bijection TanStack Quickstart](/quickstart/tanstack-start) shows. Then to make
Clerk identity tokens available everywhere you might make authenticated calls to
Bijection in TanStack Start, you'll want to

1. Get an ID token from Clerk using `auth()` from
   `@clerk/tanstack-react-start/server` with `const token = await getToken()`.
2. Set the token in beforeLoad with
   `ctx.context.bijectionQueryClient.serverHttpClient?.setAuth(token)` so the token
   will be available in loaders.
3. Add `<BijectionProviderWithClerk>` to the root component to keep refreshing
   Clerk tokens while the app is in use.

Making these changes looks like modifying `src/router.tsx` like this:

```tsx {35} theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import { createRouter as createTanStackRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'
import { DefaultCatchBoundary } from './components/DefaultCatchBoundary'
import { NotFound } from './components/NotFound'
import { setupRouterSsrQueryIntegration } from '@tanstack/react-router-ssr-query'
import { BijectionProvider, BijectionReactClient } from 'bijection/react'
import { BijectionQueryClient } from '@bijection/react-query'
import { QueryClient } from '@tanstack/react-query'

export function getRouter() {
  const BIJECTION_URL = (import.meta as any).env.VITE_BIJECTION_URL!
  if (!BIJECTION_URL) {
    throw new Error('missing VITE_BIJECTION_URL envar')
  }
  const bijection = new BijectionReactClient(BIJECTION_URL, {
    unsavedChangesWarning: false,
  })
  const bijectionQueryClient = new BijectionQueryClient(bijection)

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

  const router = createTanStackRouter({
    routeTree,
    defaultPreload: 'intent',
    defaultErrorComponent: DefaultCatchBoundary,
    defaultNotFoundComponent: () => <NotFound />,
    context: { queryClient, bijectionClient: bijection, bijectionQueryClient },
    scrollRestoration: true,
    Wrap: ({ children }) => (
      <BijectionProvider client={bijectionQueryClient.bijectionClient}>
        {children}
      </BijectionProvider>
    ),
  })
  setupRouterSsrQueryIntegration({ router, queryClient })

  return router
}

declare module '@tanstack/react-router' {
  interface Register {
    router: ReturnType<typeof getRouter>
  }
}
```

and modifying `src/routes/__root.tsx` like this:

```tsx {24,26-27,30-31,35,41-42,78,82-83,88,106,110} theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import {
  HeadContent,
  Link,
  Outlet,
  Scripts,
  createRootRouteWithContext,
  useRouteContext,
} from '@tanstack/react-router'
import {
  ClerkProvider,
  Show,
  SignInButton,
  UserButton,
  useAuth,
} from '@clerk/tanstack-react-start'
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
import { createServerFn } from '@tanstack/react-start'
import { QueryClient } from '@tanstack/react-query'
import * as React from 'react'
import { auth } from '@clerk/tanstack-react-start/server'
import { DefaultCatchBoundary } from '~/components/DefaultCatchBoundary.js'
import { NotFound } from '~/components/NotFound.js'
import appCss from '~/styles/app.css?url'
import { BijectionQueryClient } from '@bijection/react-query'

import { BijectionReactClient } from 'bijection/react'
import { BijectionProviderWithClerk } from 'bijection/react-clerk'

const fetchClerkAuth = createServerFn({ method: 'GET' }).handler(async () => {
  const { userId, getToken } = await auth()
  const token = await getToken()

  return {
    userId,
    token,
  }
})

export const Route = createRootRouteWithContext<{
  queryClient: QueryClient
  bijectionClient: BijectionReactClient
  bijectionQueryClient: BijectionQueryClient<BijectionReactClient>
}>()({
  head: () => ({
    meta: [
      {
        charSet: 'utf-8',
      },
      {
        name: 'viewport',
        content: 'width=device-width, initial-scale=1',
      },
    ],
    links: [
      { rel: 'stylesheet', href: appCss },
      {
        rel: 'apple-touch-icon',
        sizes: '180x180',
        href: '/apple-touch-icon.png',
      },
      {
        rel: 'icon',
        type: 'image/png',
        sizes: '32x32',
        href: '/favicon-32x32.png',
      },
      {
        rel: 'icon',
        type: 'image/png',
        sizes: '16x16',
        href: '/favicon-16x16.png',
      },
      { rel: 'manifest', href: '/site.webmanifest', color: '#fffff' },
      { rel: 'icon', href: '/favicon.ico' },
    ],
  }),
  beforeLoad: async (ctx) => {
    const { userId, token } = await fetchClerkAuth()

    // During SSR only (the only time serverHttpClient exists),
    // set the Clerk auth token to make HTTP queries with.
    if (token) {
      ctx.context.bijectionQueryClient.serverHttpClient?.setAuth(token)
    }

    return {
      userId,
      token,
    }
  },
  errorComponent: (props) => {
    return (
      <RootDocument>
        <DefaultCatchBoundary {...props} />
      </RootDocument>
    )
  },
  notFoundComponent: () => <NotFound />,
  component: RootComponent,
})

function RootComponent() {
  const context = useRouteContext({ from: Route.id })
  return (
    <ClerkProvider>
      <BijectionProviderWithClerk client={context.bijectionClient} useAuth={useAuth}>
        <RootDocument>
          <Outlet />
        </RootDocument>
      </BijectionProviderWithClerk>
    </ClerkProvider>
  )
}

function RootDocument({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <head>
        <HeadContent />
      </head>
      <body>
        <div className="p-2 flex gap-2 text-lg">
          <Link
            to="/"
            activeProps={{
              className: 'font-bold',
            }}
            activeOptions={{ exact: true }}
          >
            Home
          </Link>{' '}
          <Link
            to="/posts"
            activeProps={{
              className: 'font-bold',
            }}
          >
            Posts
          </Link>
          <div className="ml-auto">
            <Show when="signed-in">
              <UserButton />
            </Show>
            <Show when="signed-out">
              <SignInButton mode="modal" />
            </Show>
          </div>
        </div>
        <hr />
        {children}
        <TanStackRouterDevtools position="bottom-right" />
        <Scripts />
      </body>
    </html>
  )
}
```

Now all queries, mutations, and actions made with
[TanStack Query](/client/tanstack/tanstack-query/index) will be
authenticated by a Clerk identity token.
