Skip to main content
This is the React InstantSearch v7 documentation. If you’re upgrading from v6, see the upgrade guide. If you were using React InstantSearch Hooks, this v7 documentation applies—just check for necessary changes. To continue using v6, you can find the archived documentation.
When the <Chat> widget has no messages yet, it shows a welcome screen. Use the emptyComponent prop to replace it with your own greeting and a set of starter prompts. Each prompt sends a message to the agent when clicked, so users can start a conversation in one tap. If you only need prompt suggestions after the agent responds, use Agent Studio prompt suggestions instead.

Render starter prompts with emptyComponent

The emptyComponent receives a sendMessage function. Call it with { text } to submit a starter prompt as the first message:
React
import React from "react";
import { liteClient as algoliasearch } from "algoliasearch/lite";
import { Chat, ChatTrigger, InstantSearch } from "react-instantsearch";

const searchClient = algoliasearch(
  "ALGOLIA_APPLICATION_ID",
  "ALGOLIA_SEARCH_ONLY_API_KEY"
);

const starterPrompts = [
  "What are your best-selling headphones?",
  "Help me find a gift under $50",
  "Compare espresso machines",
];

function WelcomeScreen({ sendMessage }) {
  return (
    <div className="ais-ChatGreeting">
      <h2 className="ais-ChatGreeting-heading">How can I help you today?</h2>
      <p className="ais-ChatGreeting-subheading">
        Ask me anything about our products, or start with a suggestion.
      </p>

      <div className="ais-ChatPromptSuggestions">
        {starterPrompts.map((prompt) => (
          <button
            key={prompt}
            type="button"
            className="ais-ChatPromptSuggestions-suggestion"
            onClick={() => sendMessage({ text: prompt })}
          >
            {prompt}
          </button>
        ))}
      </div>
    </div>
  );
}

function App() {
  return (
    <InstantSearch searchClient={searchClient}>
      <Chat agentId="YOUR_CHAT_AGENT_ID" emptyComponent={WelcomeScreen} />
      <ChatTrigger />
    </InstantSearch>
  );
}
Pair <Chat> with the <ChatTrigger> widget (or AI mode on a <SearchBox>) to provide a way to open the chat.
The emptyComponent reuses the built-in classes (ais-ChatGreeting and ais-ChatPromptSuggestions) so it inherits the default styling. Replace them with your own classes to fully restyle the welcome screen.

Reuse the default greeting

Instead of writing the greeting markup yourself, render the built-in ChatGreeting component, then add your starter prompts below it. It renders the default heading and subheading, and accepts a banner image, translations, and classNames:
React
import { Chat, ChatGreeting } from "react-instantsearch";

function WelcomeScreen({ sendMessage }) {
  return (
    <>
      <ChatGreeting
        banner="https://example.com/welcome-banner.png"
        translations={{
          heading: "Welcome to our store",
          subheading: "Ask me anything, or pick a suggestion to get started.",
        }}
      />
      <div className="ais-ChatPromptSuggestions">
        {starterPrompts.map((prompt) => (
          <button
            key={prompt}
            type="button"
            className="ais-ChatPromptSuggestions-suggestion"
            onClick={() => sendMessage({ text: prompt })}
          >
            {prompt}
          </button>
        ))}
      </div>
    </>
  );
}

Fetch starter prompts dynamically

The prompts don’t have to be static. Fetch them once—for example, from a dedicated Agent Studio agent that returns starter prompts—and render them from emptyComponent:
React
import React, { useEffect, useState } from "react";

const appID = "ALGOLIA_APPLICATION_ID";
const apiKey = "ALGOLIA_SEARCH_ONLY_API_KEY";
const promptsAgentId = "YOUR_STARTER_PROMPTS_AGENT_ID";

async function getStarterPrompts() {
  const response = await fetch(
    `https://${appID}.algolia.net/agent-studio/1/agents/${promptsAgentId}/completions?stream=false&cache=true&compatibilityMode=ai-sdk-5`,
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "X-Algolia-Application-Id": appID,
        "X-Algolia-API-Key": apiKey,
      },
      body: JSON.stringify({
        messages: [
          {
            role: "user",
            parts: [{ text: "Return starter prompts for the welcome screen." }],
          },
        ],
      }),
    }
  );

  const data = await response.json();
  const text = data.parts?.find((part) => part.type === "text")?.text ?? "";

  return text
    .split("\n")
    .map((line) => line.trim())
    .filter(Boolean);
}

function WelcomeScreen({ sendMessage }) {
  const [prompts, setPrompts] = useState([]);

  useEffect(() => {
    getStarterPrompts()
      .then(setPrompts)
      .catch(() => setPrompts([]));
  }, []);

  return (
    <div className="ais-ChatGreeting">
      <h2 className="ais-ChatGreeting-heading">How can I help you today?</h2>

      <div className="ais-ChatPromptSuggestions">
        {prompts.map((prompt) => (
          <button
            key={prompt}
            type="button"
            className="ais-ChatPromptSuggestions-suggestion"
            onClick={() => sendMessage({ text: prompt })}
          >
            {prompt}
          </button>
        ))}
      </div>
    </div>
  );
}

Customize more than the empty state

The emptyComponent only replaces the initial empty state. To customize the surrounding chat layout (header, message list, prompt input), use the layoutComponent prop instead. Use ChatInlineLayout for an inline (non-overlay) layout, or ChatOverlayLayout for the default floating overlay, and reuse headerComponent, messagesComponent, and promptComponent to keep the built-in behavior.
Last modified on June 18, 2026