TanStack Start Adapter
Adapter for integrating Better Auth Studio with TanStack Start applications.
Import
import { betterAuthStudio } from 'better-auth-studio/tanstack-start';
betterAuthStudio()
Creates a TanStack Start-compatible server route handler for Better Auth Studio.
Function Signature
function betterAuthStudio(
config: StudioConfig
): ({ request }: TanStackStartHandlerContext) => Promise<Response>
Type Definitions
type TanStackStartHandlerContext = {
request: Request;
};
Parameters
Studio configuration object containing authentication and feature settings.Show StudioConfig properties
Your Better Auth instance
Base path for the studio routes. Default: "/api/studio"
Access control configuration for the studio
Customization options for branding and theming
Last-seen tracking configuration
IP geolocation provider configuration
Event tracking and ingestion configuration
Tools configuration with exclude list
Returns
An async function that accepts a handler context with a Request and returns a Response
Usage
Server Route Handler
Create a catch-all server route:
// src/routes/api/studio/$.ts
import { createFileRoute } from '@tanstack/react-router';
import { betterAuthStudio } from 'better-auth-studio/tanstack-start';
import { auth } from '~/lib/auth';
import { defineStudioConfig } from 'better-auth-studio';
const studioConfig = defineStudioConfig({
auth,
basePath: '/api/studio',
metadata: {
title: 'My App Studio',
theme: 'dark'
},
events: {
enabled: true,
tableName: 'auth_events'
}
});
const handler = betterAuthStudio(studioConfig);
export const Route = createFileRoute('/api/studio/$')({
server: {
handlers: {
GET: handler,
POST: handler,
PUT: handler,
DELETE: handler,
PATCH: handler,
},
},
});
Simplified Version
// src/routes/api/studio/$.ts
import { createFileRoute } from '@tanstack/react-router';
import { betterAuthStudio } from 'better-auth-studio/tanstack-start';
import { auth } from '~/lib/auth';
const handler = betterAuthStudio({ auth });
export const Route = createFileRoute('/api/studio/$')({
server: {
handlers: {
GET: handler,
POST: handler,
PUT: handler,
DELETE: handler,
PATCH: handler,
},
},
});
With Access Control
// src/routes/api/studio/$.ts
import { createFileRoute } from '@tanstack/react-router';
import { betterAuthStudio } from 'better-auth-studio/tanstack-start';
import { auth } from '~/lib/auth';
const handler = betterAuthStudio({
auth,
access: {
roles: ['admin'],
allowEmails: ['[email protected]']
}
});
export const Route = createFileRoute('/api/studio/$')({
server: {
handlers: {
GET: handler,
POST: handler,
PUT: handler,
DELETE: handler,
PATCH: handler,
},
},
});
With Custom Middleware
// src/routes/api/studio/$.ts
import { createFileRoute } from '@tanstack/react-router';
import { betterAuthStudio } from 'better-auth-studio/tanstack-start';
import { auth } from '~/lib/auth';
const studioHandler = betterAuthStudio({ auth });
const withLogging = async ({ request }: { request: Request }) => {
console.log(`Studio request: ${request.method} ${request.url}`);
const response = await studioHandler({ request });
console.log(`Studio response: ${response.status}`);
return response;
};
export const Route = createFileRoute('/api/studio/$')({
server: {
handlers: {
GET: withLogging,
POST: withLogging,
PUT: withLogging,
DELETE: withLogging,
PATCH: withLogging,
},
},
});
Implementation Details
Request Conversion
The adapter converts TanStack Start request objects to the universal format:
type UniversalRequest = {
url: string; // Pathname + search (with basePath stripped)
method: string; // request.method
headers: Record<string, string>; // request.headers
body?: any; // Parsed from request
};
Base Path Handling
The adapter automatically strips the base path from URLs:
// If basePath is '/api/studio'
// And request URL is '/api/studio/users'
// The universal URL will be '/users'
Content Type Handling
The adapter handles multiple content types:
application/json → request.json()
application/x-www-form-urlencoded → FormData converted to object
multipart/form-data → FormData converted to object
- Other → Attempts to parse as text, then JSON
Error Handling
Errors are caught and returned as JSON responses:
{
error: "Internal server error"
}
Status code: 500
TanStack Router Integration
File-based Routing
TanStack Start uses file-based routing with the $ parameter for catch-all routes:
src/routes/api/studio/$.ts → /api/studio/*
createFileRoute
The createFileRoute function creates type-safe route definitions:
export const Route = createFileRoute('/api/studio/$')({
server: {
handlers: {
// HTTP method handlers
},
},
});
File Structure
src/
├── routes/
│ └── api/
│ └── studio/
│ └── $.ts
└── lib/
└── auth.ts