Display a placeholder when there is no data or content to show. Commonly used inside tables, lists, or pages that have no results.
Create your first endpoint to get started.
1import { Empty } from "@ngrok/mantle/empty";2import { Button } from "@ngrok/mantle/button";3import { GhostIcon, PlusIcon } from "@phosphor-icons/react";4 5<Empty.Root>6 <Empty.Icon svg={<GhostIcon />} />7 <Empty.Title>No endpoints yet</Empty.Title>8 <Empty.Description>9 <p>Create your first endpoint to get started.</p>10 </Empty.Description>11 <Empty.Actions>12 <Button type="button" appearance="filled" priority="neutral">13 <PlusIcon />14 Create endpoint15 </Button>16 </Empty.Actions>17</Empty.Root>;A full-page error state with a retry action.
Please try again in a few minutes.
1import { Empty } from "@ngrok/mantle/empty";2import { Button } from "@ngrok/mantle/button";3import { SmileyMeltingIcon } from "@phosphor-icons/react";4 5<Empty.Root>6 <Empty.Icon svg={<SmileyMeltingIcon />} />7 <Empty.Title>Oops, something went wrong.</Empty.Title>8 <Empty.Description>9 <p>Please try again in a few minutes.</p>10 </Empty.Description>11 <Empty.Actions>12 <Button type="button" appearance="outlined" priority="neutral">13 Retry14 </Button>15 </Empty.Actions>16</Empty.Root>;A common pattern for empty states when a filter or search yields no results.
Check your spelling. It's possible what you're looking for no longer exists.
1import { Empty } from "@ngrok/mantle/empty";2import { Button } from "@ngrok/mantle/button";3import { MagnifyingGlassIcon } from "@phosphor-icons/react";4 5<Empty.Root>6 <Empty.Icon svg={<MagnifyingGlassIcon />} />7 <Empty.Title>No results matched your filter.</Empty.Title>8 <Empty.Description>9 <p>Check your spelling. It's possible what you're looking for no longer exists.</p>10 </Empty.Description>11 <Empty.Actions>12 <Button type="button" appearance="outlined" priority="neutral">13 Clear filters14 </Button>15 </Empty.Actions>16</Empty.Root>;Inside a DataTable, host Empty in DataTable.EmptyRow. The row already spans every column (auto colSpan) and Empty.Root centers itself, so you don't hand-roll a <td> or any centering. Branch on whether a filter is active to choose between the "no data yet" and "no results" copy — see the DataTable empty-states recipe for the full two-state pattern.
1import { Button } from "@ngrok/mantle/button";2import { DataTable } from "@ngrok/mantle/data-table";3import { Empty } from "@ngrok/mantle/empty";4import { MagnifyingGlassIcon } from "@phosphor-icons/react/MagnifyingGlass";5 6<DataTable.Body>7 {rows.length > 0 ? (8 rows.map((row) => <DataTable.Row key={row.id} row={row} />)9 ) : (10 <DataTable.EmptyRow>11 <Empty.Root>12 <Empty.Icon svg={<MagnifyingGlassIcon />} />13 <Empty.Title>No results matched your filter.</Empty.Title>14 <Empty.Description>15 <p>Try a different search, or clear the filter to see everything.</p>16 </Empty.Description>17 <Empty.Actions>18 <Button type="button" appearance="outlined" priority="neutral" onClick={clearFilters}>19 Clear filters20 </Button>21 </Empty.Actions>22 </Empty.Root>23 </DataTable.EmptyRow>24 )}25</DataTable.Body>;You can use only the sub-components you need.
1import { Empty } from "@ngrok/mantle/empty";2import { GhostIcon } from "@phosphor-icons/react";3 4<Empty.Root>5 <Empty.Icon svg={<GhostIcon />} />6 <Empty.Title>Nothing here</Empty.Title>7</Empty.Root>;Compose the parts of an Empty state together to build your own:
Empty.Root├── Empty.Icon├── Empty.Title├── Empty.Description└── Empty.ActionsThe root container for an empty state. Centers content horizontally with consistent vertical padding and max-width.
All props from div, plus:
Renders a large icon for the empty state. Pass a single SVG icon element via the svg prop. The icon is automatically sized to size-16.
All props from svg, plus:
The heading text for the empty state. Renders as an h3 by default. Use asChild to render as a different heading level.
All props from h3, plus:
Supporting descriptive text rendered below the title. Renders as a div with vertical spacing so multiple paragraphs can be placed inside.
All props from div, plus:
A flex container for action buttons or links.
All props from div, plus: