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.

> [!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.

> [!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.

lib/utils.ts
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.

Hello!
<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>
Previous
Organization
Next
Customization