# Chat History for LangGraph Cloud
URL: /docs/cloud/persistence/langgraph
Integrate cloud persistence and thread management with LangGraph Cloud.
Overview \[#overview]
assistant-cloud provides thread management and persistent chat history for applications built with [LangGraph Cloud](https://langchain-ai.github.io/langgraph/cloud/). This guide shows you how to integrate cloud persistence into your LangGraph application.
Prerequisites \[#prerequisites]
You need an assistant-cloud account to follow this guide. [Sign up
here](https://cloud.assistant-ui.com/) to get started.
Setup Guide \[#setup-guide]
Create a Cloud Project \[#create-a-cloud-project]
Create a new project in the [assistant-cloud dashboard](https://cloud.assistant-ui.com/) and from the settings page, copy:
* **Frontend API URL**: `https://proj-[ID].assistant-api.com`
* **API Key**: For server-side operations
Configure Environment Variables \[#configure-environment-variables]
Add the following environment variables to your project:
```bash title=".env.local"
# Frontend API URL from your cloud project settings
NEXT_PUBLIC_ASSISTANT_BASE_URL=https://proj-[YOUR-ID].assistant-api.com
# API key for server-side operations
ASSISTANT_API_KEY=your-api-key-here
```
Install Dependencies \[#install-dependencies]
Install the required packages:
Create the Runtime Provider \[#create-the-runtime-provider]
Create a runtime provider that integrates LangGraph with assistant-cloud. Choose between anonymous mode for demos/prototypes or authenticated mode for production:
```tsx title="app/chat/runtime-provider.tsx"
"use client";
import {
AssistantCloud,
AssistantRuntimeProvider,
} from "@assistant-ui/react";
import { useLangGraphRuntime } from "@assistant-ui/react-langgraph";
import { createThread, getThreadState, sendMessage } from "@/lib/chatApi";
import { LangChainMessage } from "@assistant-ui/react-langgraph";
import { useMemo } from "react";
export function MyRuntimeProvider({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const cloud = useMemo(
() =>
new AssistantCloud({
baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
anonymous: true, // Creates browser session-based user ID
}),
[],
);
const runtime = useLangGraphRuntime({
cloud,
stream: async function* (messages, { initialize }) {
const { externalId } = await initialize();
if (!externalId) throw new Error("Thread not found");
return sendMessage({
threadId: externalId,
messages,
});
},
create: async () => {
const { thread_id } = await createThread();
return { externalId: thread_id };
},
load: async (externalId) => {
const state = await getThreadState(externalId);
return {
messages:
(state.values as { messages?: LangChainMessage[] }).messages ?? [],
};
},
});
return (
{children}
);
}
```
```tsx title="app/chat/runtime-provider.tsx"
"use client";
import {
AssistantCloud,
AssistantRuntimeProvider,
} from "@assistant-ui/react";
import { useLangGraphRuntime } from "@assistant-ui/react-langgraph";
import { createThread, getThreadState, sendMessage } from "@/lib/chatApi";
import { LangChainMessage } from "@assistant-ui/react-langgraph";
import { useAuth } from "@clerk/nextjs";
import { useMemo } from "react";
export function MyRuntimeProvider({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
const { getToken } = useAuth();
const cloud = useMemo(
() =>
new AssistantCloud({
baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
authToken: async () => getToken({ template: "assistant-ui" }),
}),
[getToken],
);
const runtime = useLangGraphRuntime({
cloud,
stream: async function* (messages, { initialize }) {
const { externalId } = await initialize();
if (!externalId) throw new Error("Thread not found");
return sendMessage({
threadId: externalId,
messages,
});
},
create: async () => {
const { thread_id } = await createThread();
return { externalId: thread_id };
},
load: async (externalId) => {
const state = await getThreadState(externalId);
return {
messages:
(state.values as { messages?: LangChainMessage[] }).messages ?? [],
};
},
});
return (
{children}
);
}
```
For Clerk authentication, configure the `"assistant-ui"` token template in
your Clerk dashboard.
The `useLangGraphRuntime` hook now directly accepts `cloud`, `create`, and `load` parameters for simplified thread management. The runtime handles thread lifecycle internally.
Add Thread UI Components \[#add-thread-ui-components]
Install the thread list component:
```sh
npx assistant-ui@latest add thread-list
```
```sh
npx shadcn@latest add https://r.assistant-ui.com/thread-list.json
```
```sh
npx shadcn@latest add https://r.assistant-ui.com/thread-list.json
```
Then add it to your application layout:
```tsx title="app/chat/page.tsx"
import { Thread } from "@/components/assistant-ui/thread";
import { ThreadList } from "@/components/assistant-ui/thread-list";
export default function ChatPage() {
return (
);
}
```
Authentication \[#authentication]
The examples above show two authentication modes:
* **Anonymous**: Suitable for demos and prototypes. Creates a browser session-based user ID.
* **Authenticated**: For production use with user accounts. The authenticated example uses [Clerk](https://clerk.com/), but you can integrate any auth provider.
For other authentication providers or custom implementations, see the [Cloud Authorization](/docs/cloud/authorization) guide.
Next Steps \[#next-steps]
* Learn about [LangGraph runtime setup](/docs/runtimes/langgraph) for your application
* Explore [ThreadListRuntime](/docs/api-reference/runtimes/thread-list-runtime) for advanced thread management
* Check out the [LangGraph example](https://github.com/assistant-ui/assistant-ui/tree/main/examples/with-langgraph) on GitHub