Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.firstflow.app/llms.txt

Use this file to discover all available pages before exploring further.

Install

npm install @firstflow/nextjs

Add environment variables

# .env.local
FIRSTFLOW_AGENT_ID=your-agent-id
FIRSTFLOW_API_KEY=your-api-key
Get your agent ID and API key from the Dashboard under Settings → API keys.
When using getFirstflowConfig() for SSR prefetch, the server reads FIRSTFLOW_AGENT_ID and FIRSTFLOW_API_KEY without a NEXT_PUBLIC_ prefix. If you skip SSR prefetch and fetch client-side, expose them as NEXT_PUBLIC_FIRSTFLOW_AGENT_ID and NEXT_PUBLIC_FIRSTFLOW_API_KEY instead.

Add the provider with SSR prefetch

Call getFirstflowConfig() in your root layout (a Server Component) and pass the result as initialSdkPayload. This eliminates the client-side loading flash.
// app/layout.tsx
import { getFirstflowConfig } from "@firstflow/nextjs/server";
import { FirstflowProvider } from "@firstflow/nextjs";

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const config = await getFirstflowConfig();

  return (
    <html>
      <body>
        <FirstflowProvider
          agentId={process.env.FIRSTFLOW_AGENT_ID!}
          initialSdkPayload={config}
        >
          {children}
        </FirstflowProvider>
      </body>
    </html>
  );
}

Add the widget

FirstflowWidget and all hooks are Client Components. Add "use client" to the component that uses them.
// components/chat.tsx
"use client";

import { FirstflowWidget } from "@firstflow/nextjs";

export function Chat() {
  return (
    <FirstflowWidget experiencePlacement="inlineStack">
      <MessageList />
      <Composer />
    </FirstflowWidget>
  );
}

Pass user identity

User traits are runtime data — set them from a Client Component. Option A: Pass user in the layout if you can read session data server-side:
// app/layout.tsx
export default async function RootLayout({ children }) {
  const config = await getFirstflowConfig();
  const session = await getSession(); // your auth utility

  return (
    <html>
      <body>
        <FirstflowProvider
          agentId={process.env.FIRSTFLOW_AGENT_ID!}
          initialSdkPayload={config}
          user={session ? { id: session.userId, traits: { plan: session.plan } } : null}
        >
          {children}
        </FirstflowProvider>
      </body>
    </html>
  );
}
Option B: Call setUser() from a Client Component after login:
"use client";

import { useFirstflow } from "@firstflow/nextjs";
import { useEffect } from "react";

export function UserSync({ user }: { user: User | null }) {
  const firstflow = useFirstflow();

  useEffect(() => {
    if (user) {
      firstflow.setUser({ id: user.id, traits: { plan: user.plan } });
    } else {
      firstflow.setUser(null);
    }
  }, [user?.id]);

  return null;
}

Next steps

getFirstflowConfig

Server-side config prefetch API

Next.js reference

All exports from @firstflow/nextjs

FirstflowProvider

All provider props (shared with React)

useFirstflow()

Instance methods (shared with React)