Componentes React customizados
Defina e use componentes React personalizados em arquivos MDX com renderização no servidor, estilos Tailwind e acesso aos componentes integrados do Jamdesk.
Defina componentes React personalizados diretamente em arquivos MDX. Exporte um componente de função de seta no início do arquivo e use-o em linha. Os componentes são renderizados no servidor durante o build, com acesso a todos os componentes integrados do Jamdesk e às classes Tailwind.
Uso básico
Defina um componente usando export const no início do arquivo MDX:
export const Highlight = ({ children, color }) => (
<span style={{ backgroundColor: color, padding: '0.2em 0.4em', borderRadius: '4px' }}>
{children}
</span>
);
This text has a <Highlight color="#ffeb3b">yellow highlight</Highlight> in it.
Os nomes dos componentes devem usar PascalCase (começar com uma letra maiúscula).
Exemplo: cartão hero
Este é um exemplo mais complexo, com várias props e classes Tailwind:
export const HeroCard = ({ title, description, href, icon }) => (
<a
href={href}
className="group block p-6 rounded-lg border border-gray-200 hover:border-blue-500 transition-colors"
>
<div className="flex items-center gap-3 mb-2">
<Icon icon={icon} />
<h3 className="font-semibold text-lg">{title}</h3>
</div>
<p className="text-gray-600">{description}</p>
</a>
);
<div className="grid grid-cols-2 gap-4">
<HeroCard
title="Getting started"
description="Learn the basics"
href="/quickstart"
icon="rocket"
/>
<HeroCard
title="Components"
description="Explore available components"
href="/components/overview"
icon="puzzle-piece"
/>
</div>
Como usar componentes integrados
Seus componentes personalizados têm acesso a todos os componentes integrados do Jamdesk. Não é necessário importar nada:
export const FeatureCard = ({ title, children }) => (
<Card title={title} icon="star">
{children}
<Tip>This tip is inside a custom component!</Tip>
</Card>
);
<FeatureCard title="My Feature">
<Note>Notes work inside custom components too!</Note>
</FeatureCard>
Componentes integrados por categoria:
| Categoria | Componentes |
|---|---|
| Destaques | Note, Tip, Info, Warning, Check, Danger |
| Layout | Card, Columns, Tabs, Tab, Accordion, Steps, Step, View |
| Mídia | Frame, Icon, Badge, Tooltip |
| Código | CodeGroup |
| Documentação de API | ParamField, ResponseField, Expandable |
Limitações
- Somente funções de seta: use a sintaxe
export const. A sintaxeexport functionnão é compatível. - Sem imports: não é possível importar pacotes externos ou outros arquivos.
- Sem hooks: os hooks do React (
useState,useEffect,useRef, etc.) não estão disponíveis. Os componentes são renderizados no servidor durante o build, e os hooks só funcionam no cliente. Para componentes interativos, use arquivos de snippet (consulte a seção de solução de problemas abaixo). - Somente no servidor: os componentes são renderizados no servidor; não há interatividade no cliente nem manipuladores de eventos.
- Somente Tailwind: use classes CSS do Tailwind para estilização; CSS-in-JS não está disponível.
- Sintaxe estrita: erros de sintaxe em componentes em linha farão o build falhar com uma mensagem de erro clara.
- Nomes em PascalCase: os nomes dos componentes devem começar com uma letra maiúscula e conter somente letras e números (sem sublinhados).
Precisa de hooks do React? Os componentes em linha não podem usar useState, useEffect ou outros hooks, pois são renderizados no servidor durante o build. Para componentes interativos que precisam de estado ou efeitos, crie um arquivo de snippet com a diretiva 'use client' (consulte a seção de solução de problemas abaixo).
Práticas recomendadas
Os componentes em linha devem ser apenas de apresentação. Para lógicas complexas, solicite um componente integrado.
Garanta que seus componentes sejam acessíveis usando elementos HTML e atributos ARIA adequados.
Visualize sua documentação localmente para verificar se os componentes são renderizados corretamente nos modos claro e escuro.
Solução de problemas
Erro: Expected component 'MyComponent' to be defined
Causas:
- O nome do componente não usa PascalCase (deve começar com uma letra maiúscula)
- Erro de sintaxe na definição do componente
- Tag de fechamento ou parêntese ausente
Solução: verifique se sua exportação segue este padrão:
export const MyComponent = ({ prop }) => (
<div>{prop}</div>
);Erro: o build falha mencionando Babel ou sintaxe JSX.
Causas:
- Sintaxe JSX inválida no componente
- Tags ou colchetes não fechados
- Uso de recursos JavaScript sem suporte
Solução: verifique se seu JSX é válido. Problemas comuns:
- Todas as tags devem ser fechadas (
<img loading="lazy" />, não<img loading="lazy">) - Use
classNameem vez declass - Envolva vários elementos em um fragmento
<>...</>ou em um elemento pai
Aviso: Inline component(s) override built-in: Note
Causa: seu componente em linha tem o mesmo nome de um componente integrado.
Solução: renomeie seu componente para evitar conflitos:
// Instead of: export const Note = ...
export const CustomNote = ({ children }) => (
<div className="my-note">{children}</div>
);Problema: as classes Tailwind não funcionam.
Causas:
- Uso de CSS-in-JS ou objetos de estilo em linha (suporte limitado)
- A classe Tailwind não foi incluída no build
Solução: use classes utilitárias padrão do Tailwind. Para estilos personalizados, use a prop style em linha com valores simples:
export const Highlight = ({ children }) => (
<span style={{ backgroundColor: '#ffeb3b' }}>{children}</span>
);Problema: o componente definido com export function não é renderizado.
Causa: somente a sintaxe de função de seta export const é compatível.
Solução: converta sua função para a sintaxe de função de seta:
// Instead of:
export function MyComponent({ prop }) {
return <div>{prop}</div>;
}
// Use:
export const MyComponent = ({ prop }) => (
<div>{prop}</div>
);Problema: o componente com sublinhados ou caracteres especiais não funciona.
Causa: os nomes dos componentes devem ser identificadores PascalCase válidos (somente letras e números).
Solução: use somente letras e números no nome do componente:
// Instead of: export const Hero_Card = ...
// Instead of: export const my-component = ...
export const HeroCard = ({ title }) => (
<div>{title}</div>
);Erro: ReferenceError: useState is not defined
Causa: os hooks do React não estão disponíveis em componentes em linha. Os componentes em linha são renderizados no servidor durante o processo de build, e os hooks só funcionam em componentes React no cliente.
Solução: para componentes interativos que precisam de estado ou efeitos, crie um arquivo de snippet:
- Crie um arquivo no diretório
/snippets(por exemplo,/snippets/counter.tsx) - Adicione
'use client'no início do arquivo - Importe-o e use-o no seu MDX
'use client';
import { useState } from 'react';
export function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(c => c + 1)}>
Count: {count}
</button>
);
}import { Counter } from '/snippets/counter';
<Counter />