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