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

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

9 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.