Skip to content
KONIGI

AI Assistants / Input and invocation / Prompt starters

7 of 7

Prompt starters

An empty box tells a first-time viewer nothing about what the thing can do.

Updated September 12, 2026

Problem

A text field accepts anything, which means it suggests nothing. Someone who hasn’t used this particular assistant can’t tell whether it reads their files, searches the web, knows about their company, or only writes poems. The blank box gives them no way to find out except guessing.

Solution

Offer three or four concrete things to ask, as clickable examples that fill the composer rather than firing immediately. They do two jobs at once: they remove the cost of starting from nothing, and they teach the shape of what this assistant is for. HAX guideline 1 is exactly this, and the empty state is the highest-traffic screen in the product, so it’s the cheapest place to do it.

The quality of the examples decides whether the pattern helps or hurts. Generic starters teach that the product is a toy. Write a poem about a cat tells a professional nothing they want to know and quietly sets the register. Good starters are specific to what this assistant does better than a general one, and specific enough to be believable: summarise the attached lease and list the break clauses—not help me with a document.

Contextual beats static wherever context exists. An assistant inside a document can propose actions on that document. One inside an issue tracker can propose questions about this sprint. The starter then demonstrates the thing that actually distinguishes it, which is that it can see the work.

Quantity is a real constraint. Three or four reads as examples. A grid of twelve reads as a menu, and a menu is interpreted as the full list of what the thing can do, which is the opposite of the intended message. PAIR’s point about mental models applies directly: people build a model of the system’s scope from whatever evidence is in front of them, and a long list of options is strong evidence of a short list of capabilities.

Starters should also know when to leave. After a handful of conversations the viewer has a model, and the examples become furniture between them and the box. Fading them to a smaller treatment, or dropping to a single refresh control, keeps the screen honest for a returning user.

Use when

The assistant’s scope isn’t obvious from its surroundings, which covers nearly every general-purpose assistant and every new in-product feature.

Don’t use when

The assistant is invoked on a selection or from a command with an obvious object. Someone who highlighted a paragraph and pressed the assist key already knows what they’re asking about, and a list of unrelated suggestions gets in the way of the thing they meant to do.

Trade-offs

Starters set the ceiling as well as the floor. Whatever is on the list becomes the perceived boundary of the product, and capabilities that are absent from it are widely believed not to exist. They also bias the corpus: a product learns what people ask from what people ask, and what people ask is heavily shaped by what was suggested. Contextual starters are much better and require reading the viewer’s content to generate, which is a privacy surface on the first screen. Starters age badly. A list written at launch describes a product that has since grown, and nobody owns updating it.

Checklist

  • Do the examples show what this assistant does better than a general one?
  • Are they specific enough to be believable, or are they placeholders?
  • Do they fill the composer or fire immediately?
  • Are there three or four, or a grid that reads as a menu?
  • Do they use the viewer’s actual context when context is available?
  • What generates them, and does that involve reading the viewer’s content?
  • Do they get out of the way for a returning user?
  • Who owns updating them when the product gains a capability?
  • Is a starter reachable and readable from the keyboard?
  • Does clicking one leave the viewer able to edit before sending?

Compare

ChatGPT uses a small rotating set on the empty state and lets a click populate the composer for editing, so the example stays a starting point instead of a command. Claude leans on its project context, so the suggestions on an empty conversation inside a project are about that project’s material rather than about the product in general. Notion offers its starters at the cursor inside a page, where the options are edits to the thing being written and the context is unambiguous. Perplexity replaces starters with live example queries drawn from what people are searching right now. It teaches the shape of a good question and doubles as a browse surface.

First-run state is the whole screen these sit on. Composer is what a click populates. Command menu is the version for people who already know what they want. Inline assist is where contextual starters work best, because the object is already selected. Refusal is what happens when someone takes a starter as evidence of a capability that doesn’t exist.

Prompt starters anatomy Four specific example prompts on an empty state, drawn from the current project rather than written generically, each filling the composer rather than sending, with a twelve-item grid shown alongside as the version that reads as a menu. Four examples, or a menu that sets the ceiling Summarise the lease, list break clauses Compare Q3 spend against the forecast Draft a reply to the landlord Find every date mentioned drawn from this project reads as the full list of what it can do 1 2 3 4 1 SPECIFIC ENOUGH TO BELIEVE Write a poem about a cat teaches a professional that this is a toy. 2 FILL, DO NOT FIRE A click lands in the composer so the example stays a starting point. 3 USE THE CONTEXT An assistant that can see the work should demonstrate that in its first four lines. 4 TWELVE IS A MENU A grid sets the perceived boundary, and absent capabilities are believed absent. Starters bias the corpus. People ask what was suggested, and the product learns from that.
Wireframe — the pattern's anatomy, not any one product's version of it

Implementation

Four example prompts drawn from the current project rather than written generically, each filling the composer rather than sending. A twelve-item grid of the same idea reads as the full list of what the product can do.

shadcn
npx shadcn@latest add button
npm
lucide-react
Tokens
--card--card-foreground--background--accent--accent-foreground--muted-foreground--border--input--chart-1

PromptStarters.tsxReal buttons that fill the composer. After five conversations it fades to one refresh control.

import { RefreshCw } from "lucide-react";
import { Button } from "@/components/ui/button";

type Props = {
  /** Three or four, drawn from the current project. A grid of twelve reads
   *  as a menu, and a menu is read as the full list of what the thing can do. */
  starters: string[];
  /** Fills the composer. A click lands in the box so the example stays a
   *  starting point, and nothing is sent that the viewer did not read. */
  onPick: (text: string) => void;
  /** After a handful of conversations the viewer has a model, and the examples
   *  become furniture between them and the box. Past this many, fade to one
   *  refresh control. */
  conversations?: number;
  onRefresh?: () => void;
};

const FURNITURE_AFTER = 5;

export function PromptStarters({ starters, onPick, conversations = 0, onRefresh }: Props) {
  if (conversations >= FURNITURE_AFTER && onRefresh) {
    return (
      <Button variant="ghost" size="sm" onClick={onRefresh} className="text-muted-foreground">
        <RefreshCw className="size-4" /> suggest something
      </Button>
    );
  }

  return (
    <div className="flex flex-col gap-2">
      {starters.map((s) => (
        <Button
          key={s}
          variant="outline"
          onClick={() => onPick(s)}
          className="h-auto justify-start whitespace-normal px-3 py-2 text-left font-normal"
        >
          {s}
        </Button>
      ))}
    </div>
  );
}

demo.tsxHow it is called: four starters and a box they fill. Nothing sends.

import { useState } from "react";
import { PromptStarters } from "./PromptStarters";
import { Textarea } from "@/components/ui/textarea";

/** Four starters from the project. Picking one fills the box below it, and nothing is sent. */
export default function Demo() {
  const [draft, setDraft] = useState("");
  return (
    <div className="rounded-lg border bg-card p-4">
      <PromptStarters
        starters={[
          "Summarise the lease, list break clauses",
          "Compare Q3 spend against the forecast",
          "Draft a reply to the landlord",
          "Find every date mentioned",
        ]}
        onPick={setDraft}
      />
      <Textarea
        value={draft}
        onChange={(e) => setDraft(e.target.value)}
        rows={2}
        placeholder="Ask a question"
        aria-label="Ask a question"
        className="mt-4 resize-none"
      />
    </div>
  );
}
What it renders. Identical markup in both panes, with only the token values changing.

Examples

No captures reference this pattern yet. Captures arrive product by product; see Products for what's in the gallery so far.