React components 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 .
Example: Counter component
This example declares a Counter component and then uses it with <Counter />.
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.
React components defined in MDX files have access to all standard React hooks including useState, useEffect, useMemo, and more.
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 .
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.
Example: Color generator
This example demonstrates a more complex ColorGenerator component that uses multiple React hooks.
Create component file
Create a color-generator.jsx file in the snippets folder: /snippets/color-generator.jsx
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 >
)
}
Import and use component
Import the ColorGenerator component and use it in an MDX file: 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.
Considerations
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.
Performance best practices
When building React components for documentation, prioritize accessibility by using semantic HTML, ARIA labels, and keyboard navigation support.