# Connecting TanStack Start to Directus with the SDK 

If you're using Directus as your headless CMS and TanStack Start for your frontend, you don't need to write manual fetch calls or build your own auth headers. The Directus SDK handles all of it cleanly.

Here's how I structure a single `directus.ts` file that covers authentication, typed data fetching, filtering, CRUD operations and file uploads.

## Installing the SDK

```bash
npm install @directus/sdk
```

## Setting Up the Client

Create the client once and export it. Passing your schema type as a generic is what unlocks end-to-end type safety across every request.

```typescript
import type { Product, Navigation, CartItem, Order } from '@/types';
import {
  authentication,
  createDirectus,
  rest,
  readItems,
  createItem,
  updateItem,
  deleteItem,
  readMe,
  updateMe,
  deleteUser,
  uploadFiles,
  registerUser as registerUserDirectus,
} from '@directus/sdk';

const directusUrl =
  import.meta.env.VITE_DIRECTUS_URL ??
  process.env.VITE_DIRECTUS_URL ??
  'https://your-directus-url.com';

const directus = createDirectus(directusUrl)
  .with(authentication('session', { credentials: 'include' }))
  .with(rest({ credentials: 'include' }));
```

Using `authentication('session')` with `credentials: 'include'` means cookies are handled automatically — no manual token management needed.

## Fetching Data with Full Type Safety

Each collection gets its own exported async function with a typed return value.

```typescript
export async function getProducts(): Promise<Product[]> {
  const items = await directus.request(readItems('products'));
  return items as Product[];
}
```

## Filtering is First-Class

The SDK's filter syntax maps directly to Directus's query engine — no raw query strings, no URL building.

```typescript
export async function getProductsByCategory(
  category: string
): Promise<Product[]> {
  const items = await directus.request(
    readItems('products', {
      filter: { category: { _eq: category } },
    })
  );
  return items as Product[];
}
```

## What Else is Covered

The same client and pattern covers the full CRUD surface:

*   `readItems` — fetch collections
    
*   `createItem` — insert records
    
*   `updateItem` — update records
    
*   `deleteItem` — delete records
    
*   `uploadFiles` — handle file uploads
    
*   `readMe` / `updateMe` / `deleteUser` — user profile management
    
*   `registerUser` — user registration
    

All importable directly from `@directus/sdk` — the SDK provides typed functions and you bring your own collection types for end-to-end type safety.

## Using it in a TanStack Start Loader

TanStack Start's file-based routing and loader pattern pairs perfectly with this setup. Data is fetched server-side and ready before the component renders.

```typescript
export const Route = createFileRoute('/products')({
  loader: () => getProducts()
});
```

No boilerplate, no custom wrappers, no type assertions. One file, full coverage.

* * *

If you're evaluating Directus as a headless CMS for a TanStack Start project this setup gets you up and running quickly with a clean, maintainable data layer from day one.
