This guide assumes that you have completed the Quickstart.
An example project demonstrating implementation of this guide can be found here.
Enable thread-level sharing with the C1ShareThread component. You provide a generateShareLink(messages) function; the SDK gathers messages, opens a modal, and handles copying/confirmation.
1

Frontend: Add a Thread Share trigger

First, destructure the C1Chat component as explained the Integrating Custom Components guide, so that you can integrate a custom header. Next, use the C1ShareThread component to display a share button in your chat header, which automatically opens a modal to generate a share link using the generateShareLink function you defined.The updated code for the chat page will look something like this:
page.tsx
// ... imports

export default function Home() {
  // ... create a threadManager and threadListManager here

  const selectedThreadId = threadListManager.selectedThreadId;

  return (
    <ChatProvider
      threadListManager={threadListManager}
      threadManager={threadManager}
    >
      <Container
        logoUrl={"https://www.thesys.dev/favicon.ico"}
        agentName="C1Chat"
      >
        <SidebarContainer>
          <SidebarHeader />
          <SidebarContent>
            <NewChatButton />
            <SidebarSeparator />
            <ThreadList />
          </SidebarContent>
        </SidebarContainer>
        <ThreadContainer>
          <MobileHeader />
          <div className="flex w-full items-center justify-end p-4">
            <C1ShareThread
              generateShareLink={
                !selectedThreadId
                  ? undefined
                  : async () => {
                      const baseUrl = window.location.origin;
                      return `${baseUrl}/shared/${selectedThreadId}`;
                    }
              }
            />
          </div>
          <ScrollArea>
            <Messages />
          </ScrollArea>
          <Composer />
        </ThreadContainer>
      </Container>
    </ChatProvider>
  );
}
For details on how to create a threadManager and a threadListManager, refer to this guide
Want a custom button? Provide customTrigger to C1ShareThread:
<C1ShareThread
  customTrigger={<button>Share Thread</button>}
  generateShareLink={
    !selectedThreadId
      ? undefined
      : async () => {
          const baseUrl = window.location.origin;
          return `${baseUrl}/shared/${selectedThreadId}`;
        }
  }
/>
2

Backend: Implement the thread share endpoint

Implement an endpoint that returns the thread for a given threadId.
Implement a message store to store the message history. If you’ve followed the Quickstart, you’ll have a message store already, which you can move to a common location (such as /lib/messageStore.ts) and modify it to persist message history across API routes and requests as follows:
/lib/messageStore.ts
import OpenAI from "openai";

export type DBMessage = OpenAI.Chat.ChatCompletionMessageParam & {
  id?: string;
};

const messagesStore: {
  [threadId: string]: DBMessage[];
} = {};

export const getMessageStore = (id: string) => {
  const messageList = await fetchMessagesFromDB(id); // fetch from db here
  return {
    addMessage: (message: DBMessage) => {
      // save to db here
    },
    messageList,
  };
};
/app/api/share/[threadId]/route.ts
import { NextRequest, NextResponse } from "next/server";
import { getMessageStore } from "@/lib/messageStore";

export async function GET(
  req: NextRequest,
  { params }: { params: Promise<{ threadId: string }> }
) {
  const { threadId } = await params;

  if (!threadId) {
    return NextResponse.json(
      { error: "Thread ID is required" },
      { status: 400 }
    );
  }

  const messageStore = getMessageStore(threadId);

  return NextResponse.json(messageStore.messageList);
}
3

Test

  • Open a conversation with multiple messages.
  • Click the thread share button.
  • Generate and copy the link from the modal.
Sharing a chat thread