Web Search

The research counterpart to Task List: where that one logs the work an agent did, this logs where it went. Each step is a query it ran or a page it opened, and a step that found something branches once more into its sources, shown as overlapping site marks so a Reddit thread reads as one without anybody parsing a domain.

In a chat

Sending the message starts the trail, the sources stream in under the user turn, and the answer waits on onComplete. It shares its reveal, its clipping edge and its curved guide with Task List, so the two can sit in one thread without looking like two different products.

Send the message to start the search.

Installation

Web Search is part of BoardUI Pro.

Dark mode ready - this component follows BoardUI semantic tokens automatically. Set up theme switching.

Pro access

Web Search is a Pro component.

Your BoardUI Pro license unlocks this component and all of its source files. Activate your license once, then install it directly into your project with the CLI.

01

Activate your license

Use the key from your Lemon Squeezy purchase email. You only need to do this once per machine.

npx boardui@latest login YOUR_LICENSE_KEY
02

Install the component

The CLI copies the source and resolves every BoardUI and npm dependency for you.

npx boardui@latest add web-search

This component is included in BoardUI Pro

Get BoardUI Pro now and install it right away.

Sources

Give a step sources and it branches once more, into a Sources row carrying the marks as an overlapping stack. A table of five URLs is the heaviest thing that can appear in a thread and nobody reads it mid-run; what a reader wants at a glance is where the agent looked, which recognisable marks answer instantly. Each carries its title and domain on hover, lifts clear of its neighbours, and becomes a link when you pass an href. Past six, the rest collapse into a count.

{ label: "Component library pricing", meta: "5 results", sources: [ { title: "Tailwind UI vs building your own", domain: "www.reddit.com", brand: "reddit", href: "…" }, { title: "We shipped our design system in 6 weeks", domain: "www.linkedin.com", brand: "linkedin" }, { title: "shadcn/ui — the registry model", domain: "github.com", brand: "github" }, ],}

Site marks

branddraws a site's real logo from the same 24-mark set the social buttons use, in the site's own colour. The handful whose brand colour is black take the text colour instead and invert with the theme, which is what their own guidelines ask for. Anything not in that set takes a plain icon.

// Any of the 24 marks the design system already draws.{ label: "Searched Reddit for", query: "component library", brand: "reddit" }{ label: "Searched X for", query: "design tokens", brand: "x" }{ label: "Checked the repo", brand: "github" } // Anything else takes a plain icon instead.{ label: "Ran 3 searches", icon: RiSearchLine }

Pacing

A search that hits cache and one that crawls five pages do not take the same time, and a log that marches at a fixed tempo reads as a list being printed rather than as work happening. Give a step dwell and the trail holds there that much longer, shimmering the whole while, before the next one lands. A step with sources splits in two: the step, then its Sources row a beat later.

While the search runs, an Agent Thinking indicator sits at the tail of the trail and moves down as each step lands, so the log always ends on what is being worked on rather than on the last thing finished. It leaves when the run completes. Pass working to relabel it, or false to drop it.

const steps = [ { label: "Ran 3 searches", icon: RiSearchLine, heading: true, dwell: 2200 }, { label: "Searching for what teams pay for", meta: "5 results", dwell: 2400, sources }, { label: "Searched X for", query: "design system pricing", brand: "x", dwell: 1900 },];

Driving it from real events

Dwells are still a stand-in for real latency. Once you have a live stream, pass revealed and advance it as each query resolves; the internal timer switches off and every animation stays the same. It counts rows, so a step carrying sources is two of them.

// One unit per row, so a step that found sources is two: the step,// then its Sources row a beat later. Advance it as each query resolves// and the internal timer stays out of the way.<WebSearch steps={steps} revealed={rowsSeen} />