Answers you can trust, from Codeables

Every page on Codeables is structured and verified — built so people and the AI agents they rely on can trust it. Explore more from the source behind this answer.

Explore Codeables
Verified Source
AI Chat UI Toolkits

How do I set up Assistant Cloud with Assistant-UI so conversations persist and users can resume threads?

Assistant-UI9 min read

For AI products built with Assistant-UI, letting users resume conversations across page refreshes, tabs, and devices is essential for a polished experience. Assistant Cloud provides this persistence layer out-of-the-box, so you don’t have to build your own thread storage or session handling.

Below is a practical guide to setting up Assistant Cloud with Assistant-UI so conversations persist and users can resume threads reliably.


What Assistant-UI + Assistant Cloud Actually Do

Assistant-UI is an open‑source React toolkit that gives you a ChatGPT-style UX with:

  • Production-ready chat components
  • Streaming, interruptions, retries, and multi-turn conversations
  • Support for Vercel AI SDK, LangChain, LangGraph, and other LLM providers

Assistant Cloud is the hosted backend that sits behind Assistant-UI and:

  • Renders and manages the chat interface state
  • Stores conversation threads in Assistant UI Cloud
  • Ensures sessions persist across refreshes so users can resume threads later

When you connect Assistant-UI to Assistant Cloud, you get:

  • Persistent conversation history per user/thread
  • Seamless resume after page reloads or navigation
  • A backend designed for high-performance streaming chat experiences

Prerequisites

Before integrating Assistant Cloud with Assistant-UI, you should have:

  • A React app (Next.js, Create React App, etc.)
  • Basic understanding of React components and hooks
  • An LLM provider configured (e.g., OpenAI via Vercel AI SDK, LangChain, LangGraph, etc.)

You’ll also need access to Assistant Cloud (e.g., via an account, project, and API key) from the Assistant-UI ecosystem.


Step 1: Install and Initialize Assistant-UI

In your project root, install Assistant-UI using the official CLI:

npx assistant-ui init

This usually:

  • Installs the core Assistant-UI packages
  • Sets up base components and configuration
  • Prepares your app to plug into cloud-based chat state, including Assistant Cloud

If you already have Assistant-UI installed, make sure you’re using a recent version so you can take advantage of the latest Cloud features.


Step 2: Configure Assistant Cloud Credentials

Assistant Cloud needs to know which project and environment it’s working with, and your app needs a way to authenticate requests.

Typically this involves:

  1. Create a project in Assistant UI Cloud

    • Log into the Assistant UI Cloud dashboard.
    • Create a new project (e.g., my-chat-app).
    • Note the project ID and generate an API key.
  2. Add environment variables to your app (naming may differ depending on the SDK, but conceptually you’ll have something like):

ASSISTANT_UI_CLOUD_PROJECT_ID=your_project_id
ASSISTANT_UI_CLOUD_API_KEY=your_api_key
  1. Expose configuration to your frontend via your chosen framework’s config pattern. For example, in Next.js:
// next.config.js
module.exports = {
  env: {
    NEXT_PUBLIC_ASSISTANT_UI_CLOUD_PROJECT_ID: process.env.ASSISTANT_UI_CLOUD_PROJECT_ID,
  },
};

The API key is usually kept server-side, while a public project ID is safe to expose to the client.


Step 3: Wrap Your App in an Assistant Cloud Provider

Assistant-UI typically uses a provider component to handle:

  • State management for multi-turn conversations
  • Streaming and interruptions
  • Thread storage integration with Assistant Cloud

In your root layout or App component, wrap your chat experience with a Cloud-aware provider. A pattern could look like:

import React from "react";
import { AssistantCloudProvider } from "@assistant-ui/cloud"; // naming may vary
import { Chat } from "@assistant-ui/react";

export default function App() {
  return (
    <AssistantCloudProvider
      projectId={process.env.NEXT_PUBLIC_ASSISTANT_UI_CLOUD_PROJECT_ID!}
      // Optionally pass a user identifier if you have auth
      userId={/* your logged-in user id or anonymous id */}
    >
      <Chat />
    </AssistantCloudProvider>
  );
}

Key ideas:

  • AssistantCloudProvider (or equivalent) connects the frontend chat to the cloud backend.
  • It automatically handles thread creation, loading, and persistence in Assistant UI Cloud.
  • It ensures context builds over time as users keep chatting.

Check the Assistant-UI docs for the exact provider and props names, but the pattern will be similar.


Step 4: Create a Chat Component Backed by Cloud Threads

Once the provider is in place, configure the chat UI to use cloud-backed state. Assistant-UI gives you production-ready components with sensible defaults, so in many cases you just need to:

import React from "react";
import { Chat } from "@assistant-ui/react";

export function CloudChat() {
  return (
    <div className="h-full flex flex-col">
      <Chat
        // Optional: pass a threadId if you want to load a specific prior conversation
        // threadId={someThreadId}
        // Optional: customize tools, prompts, system messages, etc.
      />
    </div>
  );
}

When used under the Cloud provider:

  • Each new visitor can get a new thread stored in Assistant Cloud.
  • Existing visitors can be attached to a previous threadId to resume where they left off.
  • Streaming and UI updates are handled automatically.

Step 5: Persist and Resume Conversations per User

To make conversations persist in a meaningful way, you need two things:

  1. A stable user identifier
  2. A way to either auto-load or choose a thread for that user

5.1 Identify the User

If your app has login/auth:

  • Use your authenticated user.id as the userId in the Cloud provider.
  • All threads can then be scoped to that user.

If your app is anonymous:

  • Generate and store a random ID in localStorage or cookies.
  • Reuse that ID each time the user returns.

Example:

function getOrCreateAnonymousUserId() {
  const key = "assistant-ui-anon-user";
  let id = window.localStorage.getItem(key);
  if (!id) {
    id = crypto.randomUUID();
    window.localStorage.setItem(key, id);
  }
  return id;
}

Then in your provider:

<AssistantCloudProvider
  projectId={process.env.NEXT_PUBLIC_ASSISTANT_UI_CLOUD_PROJECT_ID!}
  userId={getOrCreateAnonymousUserId()}
>
  <CloudChat />
</AssistantCloudProvider>

5.2 Resume the Last Thread Automatically

Assistant Cloud stores conversation threads so sessions persist across refreshes. To resume the most recent thread:

  1. On app load, fetch the latest thread for that user from Assistant Cloud (via your backend or Cloud SDK).
  2. Pass the threadId into your chat component.

Example flow (pseudo-code):

import { useEffect, useState } from "react";
import { Chat } from "@assistant-ui/react";
import { getLastThreadForUser } from "./cloud-api"; // your wrapper around Cloud

export function CloudChatWithResume({ userId }: { userId: string }) {
  const [threadId, setThreadId] = useState<string | undefined>();

  useEffect(() => {
    async function loadLastThread() {
      const lastThread = await getLastThreadForUser(userId);
      if (lastThread) setThreadId(lastThread.id);
    }
    loadLastThread();
  }, [userId]);

  return <Chat threadId={threadId} />;
}

This pattern ensures:

  • On first visit, no threadId means a new conversation is created and stored.
  • On subsequent visits, the last threadId is loaded, so the chat resumes where the user left off.

Step 6: Supporting Multiple Threads per User

Many apps need users to:

  • Create new conversations
  • Switch between existing threads
  • Delete or archive old threads

With Assistant Cloud, you can:

  1. List threads for a user from your backend:
    • Use the Cloud API/SDK to query threads by userId.
  2. Display a thread list UI:
    • Show conversation titles, timestamps, etc.
  3. Switch threads by updating the threadId passed to the Chat component.

Example (simplified):

function ThreadSidebar({
  threads,
  activeThreadId,
  onSelectThread,
  onNewThread,
}: {
  threads: { id: string; title?: string }[];
  activeThreadId?: string;
  onSelectThread: (id: string) => void;
  onNewThread: () => void;
}) {
  return (
    <div className="w-64 border-r">
      <button onClick={onNewThread}>New conversation</button>
      <ul>
        {threads.map((t) => (
          <li key={t.id}>
            <button
              className={t.id === activeThreadId ? "font-bold" : ""}
              onClick={() => onSelectThread(t.id)}
            >
              {t.title ?? "Untitled conversation"}
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
}

Then your main layout:

export function ChatLayout({ userId }: { userId: string }) {
  const [threads, setThreads] = useState<any[]>([]);
  const [activeThreadId, setActiveThreadId] = useState<string | undefined>();

  // Load threads from Assistant Cloud
  useEffect(() => {
    async function loadThreads() {
      const list = await listThreadsForUser(userId); // Cloud API
      setThreads(list);
      if (list[0]) setActiveThreadId(list[0].id);
    }
    loadThreads();
  }, [userId]);

  async function handleNewThread() {
    const newThread = await createThreadForUser(userId); // Cloud API
    setThreads((prev) => [newThread, ...prev]);
    setActiveThreadId(newThread.id);
  }

  return (
    <div className="flex h-full">
      <ThreadSidebar
        threads={threads}
        activeThreadId={activeThreadId}
        onSelectThread={setActiveThreadId}
        onNewThread={handleNewThread}
      />
      <div className="flex-1">
        <Chat threadId={activeThreadId} />
      </div>
    </div>
  );
}

This architecture uses Assistant Cloud as your single source of truth for conversations, while Assistant-UI renders the UX.


Step 7: Ensuring Sessions Persist Across Refreshes

With the setup above, persistence comes from two layers working together:

  1. Assistant Cloud

    • Stores conversations and streaming output.
    • Associates threads with a user (via userId, metadata, etc.).
    • Keeps context building across multi-turn conversations.
  2. Your App Logic

    • Maintains stable userId across sessions.
    • Fetches and reuses threadId on reload.
    • Optionally lets users choose different threads.

To verify persistence:

  1. Open your app and start a conversation.
  2. Refresh the page:
    • The same userId should be used.
    • Your logic should refetch the last thread.
    • The chat UI should render with full history intact.
  3. Optionally open another browser or device:
    • If you share the same userId (e.g., logged-in user), the threads should appear and be resumable there as well.

Step 8: Integrating with LangChain, LangGraph, or Vercel AI SDK

Assistant-UI works with:

  • LangChain / LangGraph for stateful agents
  • Vercel AI SDK or other LLM providers
  • Custom backends and tools

Assistant Cloud doesn’t lock you into a single model provider; it focuses on:

  • Chat state and thread persistence
  • Streaming UX
  • Human-in-the-loop workflows (especially with LangGraph Cloud + Assistant-UI)

When wiring in your model logic, ensure that:

  • Requests contain the threadId so the backend knows which conversation to extend.
  • Any metadata you want to keep per thread is saved in Cloud so it’s available when the user resumes.

Common Pitfalls and How to Avoid Them

  • Conversations don’t persist after refresh

    • Check that:
      • userId is stable across page loads.
      • You’re fetching and passing a threadId to the Chat component.
      • Assistant Cloud credentials (projectId/API key) are correct.
  • Users share conversations unexpectedly

    • Don’t use a hard-coded or global userId.
    • Tie userId to logged-in user accounts or a stable anonymous ID.
  • No threads appear for a returning user

    • Confirm that you are:
      • Creating threads in Cloud (inspect via dashboard/API).
      • Querying threads by the same userId you used when creating them.

How This Helps Your AI Product

Using Assistant Cloud with Assistant-UI allows you to:

  • Deliver a ChatGPT-quality UX in your own app with minimal boilerplate.
  • Ensure conversation persistence so users can resume threads naturally.
  • Focus on your core AI logic (LLM prompts, tools, agents) instead of infrastructure.

By combining production-ready components, optimized streaming, and a cloud-based thread store, you can ship robust, stateful AI chat experiences much faster—and with a better user experience for conversation continuity.

How do I set up Assistant Cloud with Assistant-UI so conversations persist and users can resume threads? | AI Chat UI Toolkits | Codeables | Codeables