Skip to main content

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:
  1. Textos de headline
  2. CTAs (call-to-actions)
  3. Layouts completos

Exemplo 1: Teste de Headline

Vamos testar qual headline gera mais cliques no CTA.

Criar o experimento no dashboard

  1. Acesse o dashboard do Testly
  2. Clique em “Novo Experimento”
  3. Nome: homepage-hero-headline
  4. 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

components/HeroCTA.tsx
'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.

Exemplo 4: Hero com Social Proof

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)
Aguarde pelo menos 100-200 conversões por variante antes de tomar decisões. Leia mais em Significância Estatística.

Próximos Passos