# Clerk
URL: /concepts/user-authentication/clerk
Clerk is a complete authentication and user management solution that handles authentication through middleware without requiring specific API routes. This guide shows how to integrate it with Tambo.
This guide assumes you've already set up Clerk in your Next.js application,
including middleware and sign-in/sign-up pages. If you haven't, follow the
[Clerk Next.js Quick Start](https://clerk.com/docs/quickstarts/nextjs) first.
## Installation
Install the required packages:
```bash
npm install @clerk/nextjs @tambo-ai/react
```
## Integration Options
### Server-Side Token Retrieval (Recommended)
Use this approach for better security and performance, especially when you don't need real-time authentication state changes.
```tsx title="app/layout.tsx"
import { auth } from "@clerk/nextjs/server";
import ClientLayout from "./client-layout";
export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const { getToken } = await auth();
const token = await getToken();
return (
{children}
);
}
```
```tsx title="app/client-layout.tsx"
"use client";
import { ClerkProvider } from "@clerk/nextjs";
import { TamboProvider } from "@tambo-ai/react";
import { ReactNode } from "react";
interface ClientLayoutProps {
children: ReactNode;
userToken?: string;
}
export default function ClientLayout({
children,
userToken,
}: ClientLayoutProps) {
return (
{children}
);
}
```
### Client-Side Token Retrieval
Use this approach when you need real-time authentication state management or client-side routing with authentication guards.
```tsx title="app/layout.tsx"
"use client";
import { ClerkProvider } from "@clerk/nextjs";
import ClientLayout from "./client-layout";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
{children}
);
}
```
```tsx title="app/client-layout.tsx"
"use client";
import { useAuth } from "@clerk/nextjs";
import { TamboProvider } from "@tambo-ai/react";
import { ReactNode, useEffect, useState } from "react";
interface ClientLayoutProps {
children: ReactNode;
}
export default function ClientLayout({ children }: ClientLayoutProps) {
const { getToken, isLoaded, isSignedIn } = useAuth();
const [accessToken, setAccessToken] = useState();
useEffect(() => {
async function fetchToken() {
if (isLoaded && isSignedIn) {
try {
const token = await getToken();
setAccessToken(token || undefined);
} catch (error) {
console.error("Error fetching token:", error);
}
}
}
fetchToken();
}, [isLoaded, isSignedIn, getToken]);
return {children};
}
```
## Usage
Once configured, you can use Tambo components throughout your application:
```tsx title="app/dashboard/page.tsx"
import { MessageThreadFull } from "@components/tambo/message-thread-full";
export default function Dashboard() {
return (
Dashboard
);
}
```
## Advanced Configuration
### Custom JWT Templates
For advanced use cases, you can create custom JWT templates in Clerk to include specific claims:
1. Go to your Clerk Dashboard
2. Navigate to "JWT Templates"
3. Create a new template with the claims you need
4. Use the template name when calling `getToken()`:
```tsx
const token = await getToken({ template: "your-template-name" });
```
Clerk provides JWT tokens that include the user's ID in the `sub` claim, which
is exactly what Tambo needs for user identification. The token is
automatically signed and verified by Clerk.