> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/mintlify/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# React components

> Build interactive and reusable elements with React components in your documentation.

[React components](https://react.dev) are a powerful way to create interactive and reusable elements in your documentation. Use React hooks to build dynamic interfaces that respond to user interactions.

## Using React components

You can build React components directly in your MDX files using [React hooks](https://react.dev/reference/react/hooks).

### Example: Counter component

This example declares a `Counter` component and then uses it with `<Counter />`.

```mdx theme={null}
export const Counter = () => {
  const [count, setCount] = useState(0)

  const increment = () => setCount(count + 1)
  const decrement = () => setCount(count - 1)

  return (
  <div className="flex items-center justify-center">
      <div className="flex items-center rounded-xl overflow-hidden border border-zinc-950/20 dark:border-white/20">
        <button
          onClick={decrement}
          className="flex items-center justify-center h-8 w-8 text-zinc-950/80 dark:text-white/80 border-r border-zinc-950/20 dark:border-white/20"
          aria-label="Decrease"
        >
          -
        </button>

        <div className="flex text-sm items-center justify-center h-8 px-6 text-zinc-950/80 dark:text-white/80 font-medium min-w-[4rem] text-center">
          {count}
        </div>

        <button
          onClick={increment}
          className="flex items-center justify-center h-8 w-8 text-zinc-950/80 dark:text-white/80 border-l border-zinc-950/20 dark:border-white/20"
          aria-label="Increase"
        >
          +
        </button>
      </div>
    </div>
  )
}

<Counter />
```

The counter renders as an interactive React component with increment and decrement buttons.

<Tip>
  React components defined in MDX files have access to all standard React hooks including `useState`, `useEffect`, `useMemo`, and more.
</Tip>

## Importing components

To import React components in your MDX files, the component files must be located in the `/snippets/` folder. Learn more about [reusable snippets](/create/reusable-snippets).

<Note>
  Nested imports are not supported. If a React component references other components, you must import all components directly into the parent MDX file rather than importing components within component files.
</Note>

### Example: Color generator

This example demonstrates a more complex `ColorGenerator` component that uses multiple React hooks.

<Steps>
  <Step title="Create component file">
    Create a `color-generator.jsx` file in the `snippets` folder:

    ```jsx /snippets/color-generator.jsx theme={null}
    export const ColorGenerator = () => {
      const [hue, setHue] = useState(180)
      const [saturation, setSaturation] = useState(50)
      const [lightness, setLightness] = useState(50)
      const [colors, setColors] = useState([])

      useEffect(() => {
        const newColors = []
        for (let i = 0; i < 5; i++) {
          const l = Math.max(10, Math.min(90, lightness - 20 + i * 10))
          newColors.push(`hsl(${hue}, ${saturation}%, ${l}%)`)
        }
        setColors(newColors)
      }, [hue, saturation, lightness])

      const copyToClipboard = (color) => {
        navigator.clipboard
          .writeText(color)
          .then(() => {
            console.log(`Copied ${color} to clipboard!`)
          })
          .catch((err) => {
            console.error("Failed to copy: ", err)
          })
      }

      return (
        <div className="p-4 border dark:border-zinc-950/80 rounded-xl not-prose">
          <div className="space-y-4">
            <div className="space-y-2">
              <label className="block text-sm text-zinc-950/70 dark:text-white/70">
                Hue: {hue}°
                <input
                  type="range"
                  min="0"
                  max="360"
                  value={hue}
                  onChange={(e) => setHue(Number.parseInt(e.target.value))}
                  className="w-full h-2 bg-zinc-950/20 rounded-lg appearance-none cursor-pointer dark:bg-white/20 mt-1"
                />
              </label>

              <label className="block text-sm text-zinc-950/70 dark:text-white/70">
                Saturation: {saturation}%
                <input
                  type="range"
                  min="0"
                  max="100"
                  value={saturation}
                  onChange={(e) => setSaturation(Number.parseInt(e.target.value))}
                  className="w-full h-2 bg-zinc-950/20 rounded-lg appearance-none cursor-pointer dark:bg-white/20 mt-1"
                />
              </label>

              <label className="block text-sm text-zinc-950/70 dark:text-white/70">
                Lightness: {lightness}%
                <input
                  type="range"
                  min="0"
                  max="100"
                  value={lightness}
                  onChange={(e) => setLightness(Number.parseInt(e.target.value))}
                  className="w-full h-2 bg-zinc-950/20 rounded-lg appearance-none cursor-pointer dark:bg-white/20 mt-1"
                />
              </label>
            </div>

            <div className="flex space-x-1">
              {colors.map((color, idx) => (
                <div
                  key={idx}
                  className="h-16 rounded flex-1 cursor-pointer transition-transform hover:scale-105"
                  style={{ backgroundColor: color }}
                  title={`Click to copy: ${color}`}
                  onClick={() => copyToClipboard(color)}
                />
              ))}
            </div>

            <div className="text-sm font-mono text-zinc-950/70 dark:text-white/70">
              <p>
                Base color: hsl({hue}, {saturation}%, {lightness}%)
              </p>
            </div>
          </div>
        </div>
      )
    }
    ```
  </Step>

  <Step title="Import and use component">
    Import the `ColorGenerator` component and use it in an MDX file:

    ```mdx theme={null}
    import { ColorGenerator } from "/snippets/color-generator.jsx"

    <ColorGenerator />
    ```

    The color generator renders as an interactive React component with sliders to adjust hue, saturation, and lightness.
  </Step>
</Steps>

## Considerations

<AccordionGroup>
  <Accordion title="Client-side rendering impact">
    React hook components render on the client-side, which has several implications:

    * **SEO**: Search engines might not fully index dynamic content.
    * **Initial load**: Visitors may experience a flash of loading content before components render.
    * **Accessibility**: Ensure dynamic content changes are announced to screen readers.
  </Accordion>

  <Accordion title="Performance best practices">
    * **Optimize dependency arrays**: Include only necessary dependencies in your `useEffect` dependency arrays.
    * **Memoize complex calculations**: Use `useMemo` or `useCallback` for expensive operations.
    * **Reduce re-renders**: Break large components into smaller ones to prevent cascading re-renders.
    * **Lazy loading**: Consider lazy loading complex components to improve initial page load time.
  </Accordion>
</AccordionGroup>

<Tip>
  When building React components for documentation, prioritize accessibility by using semantic HTML, ARIA labels, and keyboard navigation support.
</Tip>
