Article
A long-form document in the chat, from a brief or an explainer to a fetched article in reader view.
≈ 2,428 tokens per use (tool 1,502 · guidance 219 · typical payload 707)How token costs are estimated
Example: Article
Open this article in reader view: fieldjournal.example/2026/09/hedgerows-are-coming-back
The hedgerows are coming back
Arden Valley is replanting its hedges.
Mara LindqvistThe Field Journal (opens in a new tab)

On a wet morning in late August, Tom Archer walks the edge of his east field with a spade over his shoulder and a bundle of hawthorn whips under his arm. Forty years ago his father tore out the hedge that stood here to make room for a bigger combine. This winter, Tom is putting it back.
He isn't alone. Across the Arden Valley, eleven farms have signed up to a replanting scheme run by the valley's farmers' cooperative, and together they plan to restore almost nine kilometers of hedgerow by next spring.
My dad wasn't wrong for his time. The machines got bigger and the hedges were in the way. But we lost more than we gained, and you only see that when the soil starts blowing off the field.

Shelter, soil and birds
The case for hedges is partly practical. They break the wind, which slows soil erosion on exposed fields, and they give livestock shade and shelter. They also act as corridors for wildlife, linking patches of woodland that would otherwise be cut off from one another.
Priya Nandakumar, who coordinates the scheme for the cooperative, says the farmers are motivated by more than grants. "People remember the birds," she says. "Everyone over sixty here can tell you about the yellowhammers. They want their grandchildren to hear them too."
A slow return
None of this happens quickly. A newly planted hedge needs years of cutting and laying before it becomes the dense, stock-proof barrier the old ones were. Archer expects to be in his seventies before the east field looks the way it did when he was a boy.
He doesn't seem to mind. "You don't plant a hedge for yourself," he says, pressing the soil down around the last whip of the morning. "You plant it for whoever farms here next."
When to use
- The user asked for a document to read or keep: a brief, an explainer, a how-to, a report.
- The user asked to read a fetched web article in reader view.
When not to use
- A few paragraphs answer the question. Reply in text.
- The user needs the overview at a glance. Use a Summary Card.
- The answer is a short reply with sources. Use Citations.
How the agent should use it
- Structure it with headings. Level 2 for sections (they make up the contents list), level 3 for subsections. Don't repeat the title as a heading.
- Write the full content. Every block is shown expanded.
- Only cite sources you retrieved, with
[n]right after the claim, wherenis the source's position insources. - For a fetched article, keep the byline, date and text exactly as published. Leave out images you can't link directly.
- Use callouts sparingly, for a real note or warning.
How it works
- The title is an
h2inside the chat, so the document's own headings render ash3andh4and the page outline stays valid. - The text scrolls inside the card, so a long article never makes the card taller than a screen.
- The contents list is a compact, wrapping row of links. It shows by default with three or more level-2 headings, or whenever
tocistrue. Its links scroll the text smoothly to each section (instantly with reduced motion), and the section being read is marked witharia-current="location". - Inline markup in paragraphs, list items, quotes, callouts and table cells:
**bold**,*italic*,`code`,[text](https://…)links and[n]citation markers. It's parsed by a small tokenizer, never injected as HTML. - Citation markers work like Citations: hovering or focusing one previews the source, and clicking it jumps to the numbered sources list.
- Header: the title, the subtitle and one meta line (author, publication, date). When
byline.urlis set, the publication name links to the original. - Footer actions: Copy (the article as Markdown) and Download (a
.mdfile, an icon button labelled "Download as Markdown"). - Streaming: blocks appear as they arrive, a paragraph that's still being written shows its partial text (unclosed
**styles the rest; a half-written link or marker is hidden), and the contents list updates live.
Safety
- Only
http:andhttps:URLs become links or images. Ajavascript:or other link renders as its plain text, and an image with an unsafesrcis left out. - External links open in a new tab with
rel="noopener noreferrer nofollow". - The Markdown export drops unsafe links and images too.
Installation
npx shadcn@latest add https://your-site.com/r/article.json
Usage
The footer actions don't change what the agent does, so the tool can return immediately:
import { tool } from "ai"
import { articleTool } from "@/components/genui/article.schema"
const tools = {
[articleTool.name]: tool({
description: articleTool.description,
inputSchema: articleTool.inputSchema,
execute: async () => ({ shown: true }),
}),
}Render it through the Renderer under show_article, or directly. onResult reports which action the user took, for analytics:
<Article
{...part.input}
status={part.state === "input-streaming" ? "streaming" : "ready"}
onResult={(r) => track("article_action", r)} // { action: "copy" | "download" | "open-original" }
/>The article never locks, so there's no finished state to restore from history.
With LangGraph
Push it from a graph node with ui.push({ name: "show_article", props }, { message }), and render the thread's UI messages with the Renderer.
Schema
| Prop | Type | Notes |
|---|---|---|
title | string | |
subtitle | string? | One line under the title |
byline | { author?, publication?, url? } | Data-bound for fetched articles. url links the publication name to the original (reported as open-original) |
publishedAt | string? | ISO date |
hero | { src, alt, caption? } | Optional lead image, http(s) only |
blocks | Block[] | 1–150 blocks, see below |
sources | { id, title, publisher?, url }[] | Data-bound. What the [n] markers point to |
toc | boolean? | Default: on with 3+ level-2 headings |
Block type | Fields |
|---|---|
heading | level (2 or 3), text, id? |
paragraph | text (inline markup) |
list | items (inline markup), ordered? |
quote | text, cite? |
callout | tone (note or warning), text |
image | src, alt, caption? |
code | code, language? |
table | columns, rows |
divider | |
keyFacts | items: { label, value }[] (2–8) |
Host props: status (streaming or ready), onResult and className.