# Custom components

Any React component can be used in a story. Declare a module in the configuration:

```ts title="recit.config.ts"
export default defineConfig({ components: "./components/index.tsx" });
```

```tsx title="components/index.tsx"
import { useState } from "react";

export const Counter = ({ start = 0 }: { start?: number }) => {
  const [count, setCount] = useState(start);
  return (
    <button onClick={() => setCount((c) => c + 1)}>Clicks: {count}</button>
  );
};
```

In a site, pass the same module in the `publish` section of `recit.config.ts`:

```ts title="recit.config.ts"
import { defineConfig } from "recit/config";
import * as components from "./components/index.js";

export default defineConfig({
  navigation: [],
  publish: { routePrefix: "/present", layout: "none", components },
});
```

## Live demo

<StoryEmbed slug="custom-components" />

## Syntax

```md title="Markdown"
:::component{name=Metric value="98 %" label="Lorem ipsum" trend="+2 pts"}
:::
```

```mdx title="MDX"
<Counter start={1} />
```

## Attributes and props

| Attribute | Type     | Default | Description                                        |
| --------- | -------- | ------- | -------------------------------------------------- |
| `name`    | `string` | —       | Exported name of the component (required)          |
| any other | `string` | —       | Passed as a prop (Markdown attributes are strings) |

React is provided by the engine. Style a component with a CSS module next to it
(`Counter.module.css`, imported as `classes`), or with the stylesheet of `theme.customCss`: utility
classes are not compiled.

## In other formats

<FormatSupport />
