MDX components

Tabs

Present alternative code samples and content in a tabbed interface using the Tabs component

Tabs

Use the Tabs component to show alternatives that reach the same goal in one place, such as package manager commands, per-language code samples, or per-platform instructions. Readers pick one option and see only its content, which keeps long pages short.

When to use tabs

Use tabs when the reader needs only one of several equivalent options:

  • Package managers: npm, pnpm, and bun install commands.

  • Languages: the same API call in TypeScript or cURL.

  • Operating systems: setup commands for macOS, Linux, and Windows.

  • Platforms: instructions for a hosted service versus a local tool.

Do not use tabs for content that the reader must read in order. Use a numbered procedure with Step instead. Do not hide information that every reader needs behind a tab.

Example

The following block renders three package manager alternatives. Each tab shows one command.

bash
npm install @acme/widget

Syntax

Wrap one TabsList and one TabsContent per option inside a Tabs element. Each TabsList holds TabsTrigger elements, and each trigger's value must match the value of a TabsContent.

tsx
<Tabs defaultValue="npm">
  <TabsList>
    <TabsTrigger value="npm">npm</TabsTrigger>
    <TabsTrigger value="pnpm">pnpm</TabsTrigger>
  </TabsList>
  <TabsContent value="npm">

```bash
npm install @acme/widget
```

  </TabsContent>
  <TabsContent value="pnpm">

```bash
pnpm add @acme/widget
```

  </TabsContent>
</Tabs>

Put a blank line before and after each code fence inside TabsContent. Without the blank lines, the fence may not render as a code block.

Props

ComponentPropTypeRequiredDescription
TabsdefaultValuestringRecommendedThe value of the tab that is open when the page loads. It should match a TabsTrigger.
TabsclassNamestringNoSpacing adjustments only.
TabsTriggervaluestringYesThe key for one option. Must match a TabsContent value.
TabsContentvaluestringYesThe key of the content shown when its trigger is selected.

Trigger labels are the text between the TabsTrigger tags. Keep labels short, such as npm or TypeScript.

Per-language examples

Use one tab per language when the same operation has different syntax in each language. Keep the variants equivalent so that readers can switch without losing context.

typescript
import { Widget } from "@acme/widget";

const widget = new Widget({ apiKey: process.env.WIDGET_API_KEY });

Set WIDGET_API_KEY in your environment instead of writing a real key into the page.

Tabs inside steps

A Tabs block can sit inside a StepItem when one step has alternatives. For example, a setup step can offer npm, pnpm, and bun commands while the other steps stay the same for every reader.

Common mistakes

  • Mismatched values. A TabsTrigger without a matching TabsContent shows an empty panel. Check that every value is spelled the same way.

  • Missing defaultValue. Set it to the value of the option you want shown first.

  • Unsupported component names. Only Tabs, TabsList, TabsTrigger, and TabsContent render. Names such as Tab or TabPanel do not.

  • Missing language identifier. Give every code fence inside a tab a language, such as bash, ts, or python, so the code is highlighted and copyable.