Components & syntax
Custom components you can use in MDX pages.
Alerts
Alerts are an extension of the blockquote syntax that you can use to emphasize critical information, working similarly to how they do on GitHub. To turn a blockquote into an alert, simply start it with the correct prefix for the type you want.
Info alerts
For info alerts, use the [!INFO]
prefix.
This is an alert with some info.
Note
There should be some important info here. Unfortunately, I couldn't come up with any.
> [!INFO]
> This is an alert with some info.
> [!INFO] Note
>
> There should be some important info here. Unfortunately, I couldn't come up with any.
Danger alerts
For danger alerts, use the [!DANGER]
prefix.
This is an alert with a warning or negative message.
Warning!
This is the most dangerous alert you have ever seen. But not really.
> [!DANGER]
> This is an alert with a warning or negative message.
> [!DANGER] Warning!
>
> This is the most dangerous alert you have ever seen. But not really.
Cards
Cards can be used as links to other pages, organized in a grid. Each card includes a title and an optional description.
<Cards>
<Card
title='Markdown test'
description='Just some random text to test markdown features.'
href='/sample/markdown-test'
/>
<Card
title='MDX test'
description='Same as markdown test but specifically for testing MDX components.'
href='/sample/mdx-test'
/>
</Cards>
Code blocks
Code blocks allow you to display code snippets with syntax highlighting, using Shiki. Each code block also includes a copy button to copy to code within it to the clipboard.
```tsx
import { useState } from 'react';
const Counter = () => {
const [count, setCount] = useState(0);
return (
<>
<div>{count}</div>
<button onClick={() => setCount(prev => prev + 1)}>{count}</button>
</>
);
};
```
Code block title
You can also add a title to a code block, such as a file name.
import { type ClassValue, clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
export const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs));
```ts title="lib/utils.ts"
import { type ClassValue, clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
export const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs));
```
Steps
The Steps
component renders a numbered set of steps, useful for displaying step-by-step instructions. It turns each h3
heading within it into a step heading with a number.
Do a thing
This thing is very important! You should do it.
Do another thing
This other thing is not as important as the first one, but you should do it anyway.
That's it lol
There isn't really a third thing to do, I just felt like having three steps here is better.
<Steps>
### Do a thing
This thing is very important! You should do it.
### Do another thing
This other thing is not as important as the first one, but you should do it anyway.
### That's it lol
There isn't really a third thing to do, I just felt like having three steps here is better.
</Steps>
Tabs
The Tabs
component allows you to organize content into multiple tabs, displaying the content of one tab at a time.
<Tabs items={['Hello', 'World']}>
<Tab>**Hello!**</Tab>
<Tab>**World!**</Tab>
</Tabs>
Default selected tab
By default the first tab will be selected, however this can be changed using an optional defaultIndex
prop.
<Tabs items={['Hello', 'World']} defaultIndex={1}>
<Tab>**Hello!**</Tab>
<Tab>**World!**</Tab>
</Tabs>
Shared value
You can also add an id
prop to your tabs - this will allow storing the selected tab's value in localStorage
, which would persist across page reloads.
npx shadcn@latest init
If multiple Tabs
components with the same id
exist on the same page, they will sync with each other!
npm install react-transition-switch
<Tabs id='packageManager' items={['npm', 'yarn', 'pnpm', 'bun']}>
<Tab>
```
npx shadcn@latest init
```
</Tab>
<Tab>
```
yarn dlx shadcn@latest init
```
</Tab>
<Tab>
```
pnpm dlx shadcn@latest init
```
</Tab>
<Tab>
```
bunx --bun shadcn@latest init
```
</Tab>
</Tabs>