Tabs
The Tabs component lets readers switch between multiple versions of content without leaving the page. The primary use case in technical documentation is showing the same command or code snippet for different package managers or languages.
When to use Tabs
Good uses of Tabs:
- Package manager commands - pnpm, npm, yarn variants of the same install command
- Language-specific examples - TypeScript vs JavaScript versions of a snippet
- Framework comparisons - Next.js vs Remix vs Astro setup instructions
- OS-specific commands - macOS vs Linux vs Windows shell commands
Avoid Tabs for content that is truly different per audience. If the TypeScript and JavaScript versions of your example are substantially different, they are better as separate sections or pages. Tabs work best when the content is nearly identical with small variations.
Usage
The items prop takes an array of objects. Each object has a label (the tab button text) and children (the content shown when that tab is active).
<Tabs>
<Tab label="pnpm"><pre><code>pnpm add @acme/sdk</code></pre></Tab>
<Tab label="npm"><pre><code>npm install @acme/sdk</code></pre></Tab>
<Tab label="yarn"><pre><code>yarn add @acme/sdk</code></pre></Tab>
</Tabs>Props
| Prop | Type | Description |
|---|---|---|
items | TabItem[] | Array of tab objects to render |
items[].label | string | Text shown on the tab button |
items[].children | React.ReactNode | Content rendered when the tab is active |
Tab state is local to each Tabs instance. Selecting "npm" in one Tabs component does not update other Tabs components on the same page. If you need synchronized tabs across the page, you would need to implement a shared state context - this is outside the scope of the default DocsKit setup.
Live example - package manager install
pnpm add @acme/sdkFramework-specific examples
Tabs are not limited to simple <pre><code> blocks. You can put any React content inside a tab. Here is a real-world example showing initialization code for three different frameworks. In each case, the API key is read from an environment variable on the server:
<Tabs>
<Tab label="Next.js"><pre><code>import { AcmeClient } from "@acme/sdk";
export const acme = new AcmeClient({
apiKey: process.env.ACME_API_KEY,
});</code></pre></Tab>
<Tab label="Remix"><pre><code>import { AcmeClient } from "@acme/sdk";
export const acme = new AcmeClient({
apiKey: process.env.ACME_API_KEY,
});</code></pre></Tab>
<Tab label="Express"><pre><code>const { AcmeClient } = require("@acme/sdk");
const acme = new AcmeClient({
apiKey: process.env.ACME_API_KEY,
});</code></pre></Tab>
</Tabs>For full syntax highlighting inside tabs, use a syntax-highlighted code block component approach or convert the tab children to a pre-compiled component. The <pre><code> approach is the simplest option that works with MDX static export.
Tabs inside Steps
Tabs and Steps compose naturally. The most common pattern is showing package manager options at the install step of a larger workflow. See the Steps documentation for a complete example.
Choosing good tab labels
Keep tab labels short - they appear as buttons and long labels push other tabs off-screen on mobile. Use the conventional short form:
- "pnpm" not "pnpm (recommended)"
- "npm" not "npm / npx"
- "TypeScript" not "TypeScript (.ts)"
- "macOS" not "macOS / Linux (Bash)"
Put the most common or recommended option first. The first tab is selected by default and most readers won't switch unless they need to.