Pré-requisitos
Antes de começar, você precisa ter:
Conta Criada
Uma conta criada na plataforma Testly
Projeto React
React 16.8+ ou Next.js funcionando
API Key
Sua chave de API (encontrada no dashboard)
Node.js
Node.js 14+ instalado
Instalação
Passo 1: Instale o pacote
npm install @testlyjs/react
Envolva sua aplicação com o TestlyProvider no arquivo principal (geralmente App.tsx ou _app.tsx no Next.js):
React (Vite/CRA)
Next.js (App Router)
Next.js (Pages Router)
import { TestlyProvider } from '@testlyjs/react';
import { Main } from './components/Main';
function App() {
return (
<TestlyProvider
apiKey={process.env.REACT_APP_TESTLY_API_KEY}
config={{
debug: process.env.NODE_ENV === 'development'
}}
>
<Main />
</TestlyProvider>
);
}
export default App;
import { TestlyProvider } from '@testly/react';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="pt-BR">
<body>
<TestlyProvider
apiKey={process.env.NEXT_PUBLIC_TESTLY_API_KEY}
config={{
debug: process.env.NODE_ENV === 'development'
}}
>
{children}
</TestlyProvider>
</body>
</html>
);
}
import type { AppProps } from 'next/app';
import { TestlyProvider } from '@testly/react';
export default function App({ Component, pageProps }: AppProps) {
return (
<TestlyProvider
apiKey={process.env.NEXT_PUBLIC_TESTLY_API_KEY}
config={{
debug: process.env.NODE_ENV === 'development'
}}
>
<Component {...pageProps} />
</TestlyProvider>
);
}
Variáveis de ambiente:
- React/Vite: Use
REACT_APP_TESTLY_API_KEY ou VITE_TESTLY_API_KEY
- Next.js: Use
NEXT_PUBLIC_TESTLY_API_KEY
Nunca commite sua API Key no código!
Passo 3: Crie um arquivo .env
Crie um arquivo .env na raiz do projeto:
REACT_APP_TESTLY_API_KEY=sua_api_key_aqui
# ou para Next.js:
# NEXT_PUBLIC_TESTLY_API_KEY=sua_api_key_aqui
Adicione .env ao seu .gitignore:
Seu Primeiro Experimento
Vamos criar um teste A/B simples para um botão de CTA.
Passo 1: Crie o experimento no dashboard
- Acesse o dashboard do Testly
- Clique em “Novo Experimento”
- Dê um nome:
homepage-cta-test
- Crie duas variantes:
- Variante A (Controle): “Comece Grátis”
- Variante B (Tratamento): “Experimente Agora”
- Copie o Experiment ID gerado (ex:
homepage-cta-test)
Passo 2: Implemente o hook useExperiment
Crie um componente que usa o teste A/B:
components/HeroSection.tsx
import { useExperiment } from '@testly/react';
export function HeroSection() {
const { variant, loading, error, convert } = useExperiment('homepage-cta-test');
// Loading state
if (loading) {
return (
<div className="hero">
<h1>Transforme seu produto com dados</h1>
<div className="skeleton-button" /> {/* Placeholder */}
</div>
);
}
// Error fallback
if (error) {
console.error('Erro ao carregar experimento:', error);
return (
<div className="hero">
<h1>Transforme seu produto com dados</h1>
<button onClick={() => window.location.href = '/signup'}>
Comece Grátis
</button>
</div>
);
}
// Render variants
return (
<div className="hero">
<h1>Transforme seu produto com dados</h1>
{variant === 'variant-b' ? (
<button
className="cta-button"
onClick={() => {
convert('cta_clicked');
window.location.href = '/signup';
}}
>
Experimente Agora 🚀
</button>
) : (
<button
className="cta-button"
onClick={() => {
convert('cta_clicked');
window.location.href = '/signup';
}}
>
Comece Grátis
</button>
)}
</div>
);
}
Boas práticas:
- Sempre implemente estados de
loading e error
- Use um fallback que mantenha a funcionalidade do site
- Chame
convert() quando a ação desejada acontecer
Passo 3: Use o componente
import { HeroSection } from '../components/HeroSection';
export default function Home() {
return (
<main>
<HeroSection />
{/* Resto da página */}
</main>
);
}
Tracking de Conversões
O Testly oferece duas formas de rastrear conversões:
1. Conversão Específica (Recomendado)
Use quando a conversão está diretamente relacionada ao experimento:
const { variant, convert } = useExperiment('pricing-test');
<button onClick={() => convert('plan_selected')}>
Selecionar Plano Premium
</button>
✅ Vantagens:
- Mais preciso
- Não gera “ruído” em outros experimentos
- Performance melhor
2. Conversão Global
Use quando uma ação deve contar para todos os experimentos ativos:
import { useConversion } from '@testly/react';
function CheckoutButton() {
const trackGlobal = useConversion();
return (
<button onClick={() => trackGlobal('purchase_completed')}>
Finalizar Compra
</button>
);
}
✅ Quando usar:
- Eventos de negócio importantes (compras, cadastros)
- Ações que impactam múltiplos experimentos
- Métricas globais do funil
Exemplo Completo: Landing Page
Aqui está um exemplo completo de uma landing page com múltiplos testes A/B:
import { useExperiment, useConversion } from '@testly/react';
function HeroSection() {
const { variant, convert } = useExperiment('hero-headline-test');
return (
<section className="hero">
{variant === 'variant-b' ? (
<h1>Valide suas ideias com dados reais</h1>
) : (
<h1>Teste A/B para founders devs</h1>
)}
<button onClick={() => convert('hero_cta_clicked')}>
Começar Grátis
</button>
</section>
);
}
function PricingSection() {
const { variant, convert } = useExperiment('pricing-layout-test');
if (variant === 'variant-b') {
return (
<section className="pricing-3-columns">
{/* Layout com 3 colunas */}
<PricingCard
plan="Free"
onSelect={() => convert('plan_selected')}
/>
<PricingCard
plan="Pro"
onSelect={() => convert('plan_selected')}
/>
<PricingCard
plan="Enterprise"
onSelect={() => convert('plan_selected')}
/>
</section>
);
}
return (
<section className="pricing-2-columns">
{/* Layout com 2 colunas */}
<PricingCard
plan="Free"
onSelect={() => convert('plan_selected')}
/>
<PricingCard
plan="Pro"
onSelect={() => convert('plan_selected')}
/>
</section>
);
}
function SignupButton() {
const trackGlobal = useConversion();
const handleSignup = () => {
trackGlobal('signup_completed'); // Conta para TODOS os experimentos
window.location.href = '/dashboard';
};
return (
<button onClick={handleSignup}>
Criar Conta Grátis
</button>
);
}
export default function LandingPage() {
return (
<main>
<HeroSection />
<PricingSection />
<SignupButton />
</main>
);
}
Configuração Avançada
Debug Mode
Ative logs detalhados durante o desenvolvimento:
<TestlyProvider
apiKey="YOUR_API_KEY"
config={{
debug: process.env.NODE_ENV === 'development',
dedupConversions: true // Padrão, previne conversões duplicadas
}}
>
Logs que você verá:
[Testly] ✅ Experiment loaded: homepage-cta-test
[Testly] 👤 User assigned to: variant-b
[Testly] 📊 Impression recorded
[Testly] 🎯 Conversion recorded: cta_clicked
Variantes Customizadas
Você pode renderizar qualquer coisa baseado na variante:
const { variant } = useExperiment('feature-test');
return (
<div>
{variant === 'variant-b' && <NewFeature />}
{variant === 'variant-c' && <AlternativeFeature />}
{variant === 'control' && <OriginalFeature />}
</div>
);
Múltiplos Experimentos
Você pode rodar vários experimentos na mesma página:
function ProductPage() {
const heroTest = useExperiment('hero-test');
const pricingTest = useExperiment('pricing-test');
const ctaTest = useExperiment('cta-test');
return (
<>
<Hero variant={heroTest.variant} convert={heroTest.convert} />
<Pricing variant={pricingTest.variant} convert={pricingTest.convert} />
<CTA variant={ctaTest.variant} convert={ctaTest.convert} />
</>
);
}
Troubleshooting
Erro: 'TestlyProvider' não encontrado
Solução: Certifique-se de que instalou o pacote corretamente:npm install @testly/react
E que está importando corretamente:import { TestlyProvider } from '@testly/react';
Variante não muda ao recarregar
Isso é esperado! O SDK usa cache local para manter consistência.Para testar diferentes variantes:
- Abra o DevTools (F12)
- Vá em Application → Local Storage
- Limpe as chaves que começam com
testly-
- Recarregue a página
Ou use navegação anônima para cada teste. Conversões não aparecem no dashboard
Checklist:
- ✅ Você chamou
convert('event_name')?
- ✅ O evento está sendo disparado (verifique com
debug: true)?
- ✅ Sua API Key está correta?
- ✅ O experimento está ativo no dashboard?
Ative o debug mode e verifique os logs:
Esse erro significa que algum ID está faltando. Verifique:
- O
experimentId passado para useExperiment() está correto?
- O experimento existe no dashboard?
- A API Key tem permissão para acessar esse experimento?
Exemplo correto:useExperiment('homepage-cta-test') // ID do dashboard
TypeScript: Tipos não encontrados
O pacote já vem com tipos incluídos. Se tiver problemas:{
"compilerOptions": {
"moduleResolution": "node",
"esModuleInterop": true
}
}
Boas Práticas
1. Sempre use fallbacks
const { variant, loading, error } = useExperiment('test');
if (loading) return <Skeleton />; // ✅ Bom
if (error) return <OriginalVersion />; // ✅ Bom
// ❌ Ruim: Não fazer nada durante loading/error
// ✅ Bom: descritivo e único
convert('hero_cta_clicked')
convert('pricing_plan_selected')
convert('trial_started')
// ❌ Ruim: genérico e ambíguo
convert('click')
convert('button')
convert('event')
3. Teste apenas UMA variável por vez
// ✅ Bom: Testa apenas o texto do botão
variant === 'b' ? 'Comece Grátis' : 'Experimente Agora'
// ❌ Ruim: Muda texto E cor E tamanho
variant === 'b' ? (
<button className="big blue">Texto Diferente</button>
) : (
<button className="small red">Texto Original</button>
)
4. Use variáveis de ambiente
// ✅ Bom
apiKey={process.env.NEXT_PUBLIC_TESTLY_API_KEY}
// ❌ Ruim: API Key hardcoded
apiKey="b4e46e6992744175dc521ac4b72f259afa648280"
5. Aguarde significância estatística
- Mínimo de 100-200 conversões por variante
- Aguarde pelo menos 1-2 semanas de teste
- Não mude variantes durante o teste
- Use calculadoras de significância estatística
Próximos Passos
Crie mais experimentos
Teste outros elementos: headlines, pricing, formulários, onboarding
Aprenda técnicas avançadas
Compartilhe resultados
Documente seus aprendizados e compartilhe com o time
Recursos Adicionais
Precisa de Ajuda?
Suporte
Entre em contato [email protected]Respondemos em até 24h (geralmente muito mais rápido!)
Dica de ouroAtive o debug: true durante o desenvolvimento. Isso vai te salvar horas de debugging! 🐛
Pronto para experimentar? Crie sua conta grátis 🚀