Visão Geral
Hero sections são perfeitas para testes A/B porque:
✅ São a primeira coisa que os usuários veem
✅ Pequenas mudanças podem ter grande impacto
✅ Conversão é fácil de medir (clique no CTA)
Neste guia, você aprenderá a testar:
Textos de headline
CTAs (call-to-actions)
Layouts completos
Exemplo 1: Teste de Headline
Vamos testar qual headline gera mais cliques no CTA.
Criar o experimento no dashboard
Acesse o dashboard do Testly
Clique em “Novo Experimento”
Nome: homepage-hero-headline
Crie as variantes:
Controle : Headline atual
Variante B : Headline alternativa
Implementação
components/HeroSection.tsx
'use client' ; // Next.js App Router
import { useExperiment } from '@testly/react' ;
export function HeroSection () {
const { variant , loading , error , convert } = useExperiment ( 'homepage-hero-headline' );
// Loading state - mantém layout estável
if ( loading ) {
return (
< section className = "hero" >
< div className = "container" >
< div className = "skeleton-title" />
< div className = "skeleton-subtitle" />
< div className = "skeleton-button" />
</ div >
</ section >
);
}
// Error state - fallback para versão original
if ( error ) {
console . error ( 'Erro ao carregar experimento:' , error );
return < HeroOriginal /> ;
}
// Headlines por variante
const headlines = {
'control' : 'A/B Testing para Founders Devs' ,
'variant-b' : 'Valide suas Ideias com Dados Reais'
};
const subtitle = 'Implemente testes A/B em 5 minutos com nosso SDK React simples e confiável.' ;
const handleCTAClick = () => {
convert ( 'hero_cta_clicked' );
window . location . href = '/signup' ;
};
return (
< section className = "hero" >
< div className = "container" >
< h1 className = "hero-title" >
{ headlines [ variant ] || headlines . control }
</ h1 >
< p className = "hero-subtitle" > { subtitle } </ p >
< button
className = "cta-primary"
onClick = { handleCTAClick }
>
Começar Grátis
</ button >
</ div >
</ section >
);
}
CSS (Tailwind)
< section className = "min-h-screen flex items-center justify-center bg-gradient-to-br from-blue-50 to-indigo-100" >
< div className = "container mx-auto px-4 text-center" >
< h1 className = "text-5xl md:text-6xl font-bold text-gray-900 mb-6" >
{ headlines [ variant ] || headlines . control }
</ h1 >
< p className = "text-xl text-gray-600 mb-8 max-w-2xl mx-auto" >
{ subtitle }
</ p >
< button
className = "bg-blue-600 hover:bg-blue-700 text-white px-8 py-4 rounded-lg text-lg font-semibold transition-colors"
onClick = { handleCTAClick }
>
Começar Grátis
</ button >
</ div >
</ section >
Resultado esperado : Você saberá qual headline gera mais cliques no CTA. Foque em testar apenas o título , mantendo todo o resto igual.
Exemplo 2: Teste de CTA
Vamos testar diferentes textos de call-to-action.
Implementação
'use client' ;
import { useExperiment } from '@testly/react' ;
export function HeroCTA () {
const { variant , loading , error , convert } = useExperiment ( 'homepage-cta-text' );
if ( loading ) return < ButtonSkeleton /> ;
if ( error ) return < DefaultCTA /> ;
const ctaTexts = {
'control' : 'Começar Grátis' ,
'variant-b' : 'Experimente Agora' ,
'variant-c' : 'Criar Conta Grátis' ,
'variant-d' : 'Testar Sem Compromisso'
};
const handleClick = async () => {
await convert ( 'cta_clicked' );
window . location . href = '/signup' ;
};
return (
< div className = "flex flex-col sm:flex-row gap-4 justify-center" >
< button
className = "bg-blue-600 hover:bg-blue-700 text-white px-8 py-4 rounded-lg font-semibold"
onClick = { handleClick }
>
{ ctaTexts [ variant ] || ctaTexts . control }
</ button >
< button
className = "bg-white hover:bg-gray-50 text-gray-900 px-8 py-4 rounded-lg font-semibold border-2 border-gray-300"
onClick = { () => window . location . href = '/demo' }
>
Ver Demo
</ button >
</ div >
);
}
Hipótese : CTAs mais específicos (“Criar Conta Grátis”) podem converter melhor que genéricos (“Começar”).
Exemplo 3: Teste de Layout Completo
Vamos testar dois layouts completamente diferentes.
Implementação
components/HeroLayoutTest.tsx
'use client' ;
import { useExperiment } from '@testly/react' ;
import Image from 'next/image' ;
export function HeroLayoutTest () {
const { variant , loading , error , convert } = useExperiment ( 'homepage-hero-layout' );
if ( loading ) return < HeroSkeleton /> ;
if ( error ) return < HeroDefault /> ;
const handleCTA = () => {
convert ( 'hero_cta_clicked' );
window . location . href = '/signup' ;
};
// Layout Centrado (Controle)
if ( variant === 'control' ) {
return (
< section className = "min-h-screen flex items-center justify-center bg-gray-50" >
< div className = "container mx-auto px-4 text-center" >
< h1 className = "text-5xl font-bold text-gray-900 mb-6" >
Testes A/B para Founders Devs
</ h1 >
< p className = "text-xl text-gray-600 mb-8 max-w-2xl mx-auto" >
Implemente experimentos em minutos, não dias. SDK simples, resultados claros.
</ p >
< button
className = "bg-blue-600 hover:bg-blue-700 text-white px-8 py-4 rounded-lg text-lg font-semibold"
onClick = { handleCTA }
>
Começar Grátis
</ button >
< div className = "mt-12" >
< Image
src = "/dashboard-preview.png"
alt = "Dashboard Preview"
width = { 800 }
height = { 500 }
className = "rounded-lg shadow-2xl mx-auto"
/>
</ div >
</ div >
</ section >
);
}
// Layout Split (Variante B)
return (
< section className = "min-h-screen flex items-center bg-white" >
< div className = "container mx-auto px-4" >
< div className = "grid md:grid-cols-2 gap-12 items-center" >
{ /* Texto à esquerda */ }
< div >
< h1 className = "text-5xl font-bold text-gray-900 mb-6" >
Valide suas ideias com dados reais
</ h1 >
< p className = "text-xl text-gray-600 mb-8" >
SDK React simples. Resultados em tempo real. Sem complexidade desnecessária.
</ p >
< div className = "flex flex-col sm:flex-row gap-4" >
< button
className = "bg-blue-600 hover:bg-blue-700 text-white px-8 py-4 rounded-lg font-semibold"
onClick = { handleCTA }
>
Começar Grátis
</ button >
< button
className = "bg-gray-100 hover:bg-gray-200 text-gray-900 px-8 py-4 rounded-lg font-semibold"
onClick = { () => window . location . href = '/demo' }
>
Ver Demo
</ button >
</ div >
< div className = "mt-8 flex items-center gap-8 text-sm text-gray-600" >
< div className = "flex items-center gap-2" >
< CheckIcon />
< span > Sem cartão de crédito </ span >
</ div >
< div className = "flex items-center gap-2" >
< CheckIcon />
< span > Setup em 5 minutos </ span >
</ div >
</ div >
</ div >
{ /* Imagem à direita */ }
< div >
< Image
src = "/dashboard-preview.png"
alt = "Dashboard Preview"
width = { 600 }
height = { 400 }
className = "rounded-lg shadow-2xl"
/>
</ div >
</ div >
</ div >
</ section >
);
}
function CheckIcon () {
return (
< svg className = "w-5 h-5 text-green-500" fill = "currentColor" viewBox = "0 0 20 20" >
< path fillRule = "evenodd" d = "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule = "evenodd" />
</ svg >
);
}
Atenção : Ao testar layouts completos, você está mudando múltiplas variáveis . Isso dificulta saber exatamente o que causou a diferença. Ideal para validar conceitos gerais, não otimizações específicas.
Vamos testar se adicionar social proof aumenta conversões.
components/HeroWithProof.tsx
'use client' ;
import { useExperiment } from '@testly/react' ;
export function HeroWithProof () {
const { variant , convert } = useExperiment ( 'homepage-hero-social-proof' );
const handleCTA = () => {
convert ( 'hero_cta_clicked' );
window . location . href = '/signup' ;
};
return (
< section className = "min-h-screen flex items-center justify-center bg-gray-50" >
< div className = "container mx-auto px-4 text-center" >
< h1 className = "text-5xl font-bold text-gray-900 mb-6" >
A/B Testing para Founders Devs
</ h1 >
< p className = "text-xl text-gray-600 mb-8 max-w-2xl mx-auto" >
Implemente experimentos em minutos com nosso SDK React simples e confiável.
</ p >
{ /* Social Proof - apenas na Variante B */ }
{ variant === 'variant-b' && (
< div className = "mb-8" >
< p className = "text-sm text-gray-500 mb-4" >
Usado por mais de 500 founders
</ p >
< div className = "flex justify-center gap-8 items-center" >
< div className = "flex -space-x-2" >
{ [ 1 , 2 , 3 , 4 , 5 ]. map (( i ) => (
< img
key = { i }
src = { `/avatars/user- ${ i } .jpg` }
alt = "User"
className = "w-10 h-10 rounded-full border-2 border-white"
/>
)) }
</ div >
< div className = "flex items-center gap-1" >
< StarIcon />
< StarIcon />
< StarIcon />
< StarIcon />
< StarIcon />
< span className = "ml-2 text-sm font-semibold text-gray-700" >
4.9/5 (120 reviews)
</ span >
</ div >
</ div >
</ div >
) }
< button
className = "bg-blue-600 hover:bg-blue-700 text-white px-8 py-4 rounded-lg text-lg font-semibold"
onClick = { handleCTA }
>
Começar Grátis
</ button >
</ div >
</ section >
);
}
function StarIcon () {
return (
< svg className = "w-5 h-5 text-yellow-400" fill = "currentColor" viewBox = "0 0 20 20" >
< path d = "M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
</ svg >
);
}
Hipótese : Social proof gera confiança e pode aumentar conversões. Este teste mostra/esconde o elemento baseado na variante.
Boas Práticas
1. Teste UMA coisa por vez
// ✅ Bom - testa apenas headline
const headlines = {
'control' : 'Headline A' ,
'variant-b' : 'Headline B'
};
// ❌ Ruim - muda headline + cor + tamanho
if ( variant === 'variant-b' ) {
return < h1 className = "text-red-500 text-6xl" > Headline B </ h1 > ;
}
2. Sempre implemente fallbacks
// ✅ Bom
if ( loading ) return < Skeleton /> ;
if ( error ) return < DefaultHero /> ;
// ❌ Ruim - pode quebrar a página
const { variant } = useExperiment ( 'test' );
return < h1 > { headlines [ variant ] } </ h1 > ; // undefined se falhar
3. Nomeie conversões claramente
// ✅ Bom
convert ( 'hero_primary_cta_clicked' )
convert ( 'hero_secondary_cta_clicked' )
// ❌ Ruim
convert ( 'click' )
convert ( 'button' )
4. Mantenha consistência visual
// ✅ Bom - mesmas classes
< button className = "cta-primary" onClick = { handleClick } >
{ ctaTexts [ variant ] }
</ button >
// ❌ Ruim - estilos diferentes
{ variant === 'b' ? (
< button className = "big-blue-button" > CTA B </ button >
) : (
< button className = "small-red-button" > CTA A </ button >
)}
Checklist de Implementação
Antes de colocar seu experimento no ar:
Experimento criado e ativo no dashboard
Loading state implementado (evita Layout Shift)
Error state com fallback funcional
Função convert() chamada na ação desejada
Testado em ambiente de desenvolvimento com debug: true
Nome do evento de conversão é descritivo
Apenas UMA variável sendo testada (headline OU CTA OU layout)
Análise de Resultados
Depois de rodar o experimento por 1-2 semanas:
No Dashboard
Você verá métricas como:
Impressões : Quantos usuários viram cada variante
Conversões : Quantos clicaram no CTA
Taxa de conversão : % de conversão por variante
Exemplo de Decisão
Variante A (Controle):
- 5.000 impressões
- 250 conversões
- Taxa: 5%
Variante B:
- 5.000 impressões
- 350 conversões
- Taxa: 7%
✅ Variante B vence! (40% de melhoria)
Próximos Passos
Pricing Page Teste diferentes estruturas de preço
Call-to-Action Otimize botões e formulários
Onboarding Flow Melhore a experiência de onboarding
Best Practices Metodologias de experimentação