Skip to main content
An experience is one thing FirstFlow delivers to a user inside your chat: an AI guide that answers a stuck user, a multi-step product tour, an NPS survey, or a one-shot announcement. Every experience renders in the same place the FirstflowWidget anchored to your composer so users are never pulled into a popup, a separate panel, or an email. You author each experience once in the dashboard, and the server decides when to show it and to whom. The catalog below is the menu of what you can build. Each experience has a single type, chosen at creation and immutable, that determines which nodes are available in the editor and how the experience renders. Read this page to pick the right type for a goal; follow the inline links into Authoring to build one and into Targeting to control who sees it.

How an experience reaches the user

The browser SDK is a passive consumer. It does not decide what to show it renders what arrives and reports activity back. Eligibility (triggers, audience, schedule, frequency, and any classifier gate) is evaluated server-side; when a user qualifies, the server walks the experience’s flow graph, composes the finished WidgetTree, and pushes it over Socket.IO. That is why you cannot trigger a widget purely from the client: you report activity by sending the conversation’s messages through the wrapped LLM client (or notifyActivity()), and the server makes the decision. Two consequences follow from this model. First, flow navigation is server-side: when a user taps a “Next” button, the widget emits a flow.next action, the backend advances the walker and composes the next step, then pushes it down the browser never holds the whole flow. Second, guides are composed at runtime by Anthropic (claude-sonnet-4-6) from live conversation context, while tours, surveys, and announcements are authored step-by-step and rendered largely as written.

The four experience types

The type you choose at creation is fixed for the life of the experience and gates everything downstream available node types in the editor, available triggers, and how the result renders.

Guide

A guide is a single AI-composed widget. The backend walks the experience’s flow graph to a terminal Result node, then hands the node’s instruction plus the live conversation context to Anthropic, which composes a rich WidgetTree headings, text, dynamic CTAs, inputs tailored to what the user is actually doing. Guides are the right choice for in-context answers, walkthroughs that adapt to the conversation, and “offer help when the user seems stuck” flows. They are typically fired by an LLM classifier trigger and default to a frequency of always. See Experiences (concept) and Flows & nodes for the graph that drives them.

Tour

A tour is a multi-step authored sequence of styled message cards that walks a user through a feature. Unlike a guide, the content is fixed at authoring time you compose message, card, rich card, quick replies, and carousel nodes in the editor, and the user steps through them with flow.next / flow.back. Use a tour when you want predictable, designed copy rather than AI-generated content. See Flows & nodes for the node types available in a tour.

Survey

A survey collects structured data natively in chat no redirect to a survey tool. You build it from question nodes: scale (NPS, slider, or opinion scale via scaleQuestionType), multiple choice, open question, checklist, and interview prompt, with text block and thank you steps in between. Responses are analytics-only: each completed survey emits a survey_completed event to ClickHouse, and there is no separate transactional response store read results through Analytics. Prior answers are addressable as answers.<questionId> in later conditions, so a survey can branch on what the user just said.

Announcement

An announcement is a one-shot in-chat notification or feature banner a single piece of content the user acknowledges and dismisses. It is the lightest type: an announcement node holds the content, optionally preceded by message nodes or branching. Use it for changelog highlights, maintenance notices, and feature launches. Pair it with a once or limited frequency so a user does not see the same banner repeatedly.

Where experiences surface

Every type renders through the same FirstflowWidget, but two surfaces change how an experience starts and where it appears. Placement is an experience setting that controls where the rendered widget sits: overlay, inline, above-composer, or full-page. It is configured per experience in the dashboard alongside triggers and audience see Triggers & audience not as a browser prop. Slash commands give users an explicit way to start an experience. A command is an AgentCommand configured per agent whose action either triggers an experience ({ type: "experience", experienceId }) or emits an app action your code handles ({ type: "action", key }). Commands arrive over the realtime connection; read them from useFirstflow().commands and trigger one programmatically:
To get the built-in / palette instead, pass your chat input’s ref to the widget see Slash commands for the full setup. Selecting an experience command tells the backend to push the linked experience; selecting an action command delivers an app.event to your onAppEvent handler.

Authoring and rendering

You build any experience three ways: by hand in the visual flow editor, by describing it in plain language for AI to generate (streamed live as it builds), or by importing a help article or feature page from a URL. Branching comes from rule-based decision nodes and LLM-based classify nodes, and mid-flow side-effects come from API call, webhook, and Slack nodes. The full toolkit lives in Authoring. Whatever the type, the runtime artifact is a WidgetTree of declarative blocks layout (stack, row, card), content (title, text, media), and interactive (button, text_input, rating, slider) primitives. The same tree renders identically in FirstFlow Cloud and in a self-hosted deployment because the schema lives in @firstflow/widget-kit.

Specific cases & limitations

An experience’s type is chosen at creation and cannot be changed. To turn a tour into a guide, create a new experience. The type gates the node registry, so the editor only ever offers nodes valid for that type.
The browser SDK reports activity; the server decides eligibility. Calling notifyActivity() or sending messages through the wrapped LLM client does not guarantee a widget triggers, audience, schedule, and frequency are all evaluated server-side. A triggerCommand for an experience command is a request the backend still resolves against the experience’s rules.
A completed survey emits a survey_completed event to ClickHouse. There is no transactional response table to query for raw answers surface results through Analytics. Within a flow, prior answers are available as answers.<questionId> for conditions.
A guide’s widget is composed at runtime by Anthropic from conversation context, so two users in different states see different content. Use a tour or announcement when you need exact, fixed copy.

Next

To build an experience, start in Authoring; to control when and to whom it shows, see Targeting. For the underlying model, read the Experiences concept and the WidgetTree and blocks that every type renders into.