Recentemente trabalhei numa landing page de um cliente de ecommerce (venda de suplemento, direct response) construída no Framer, mas com o checkout rodando fora, direto no Shopify. Cenário comum, mas que esconde uma quantidade grande de detalhes que só aparecem quando você tenta instrumentar analytics de verdade nesse tipo de estrutura.
Vou compartilhar os quatro problemas que mais me deram trabalho e como resolvi cada um, porque imagino que quem trabalha com LP de conversão no Framer + checkout externo vai esbarrar nas mesmas paredes.
Existe mais de um jeito de juntar Framer com Shopify, e vale entender onde a abordagem deste guia se encaixa antes de sair copiando código.
O que eu fiz: LP 100% construída no Framer, sem nenhum plugin de sincronização de loja. O produto, preço e variantes existem só visualmente na LP (texto e imagem, editados à mão), e o botão final de compra é um link direto pro carrinho do Shopify, no formato de cart permalink (/cart/VARIANT_ID:QTY). Não existe "adicionar ao carrinho" dentro da LP, não existe mini-carrinho, não existe sincronização automática de estoque ou preço. A pessoa clica uma vez e já cai direto na tela de checkout do Shopify, com os dados certos.
Por que escolhi assim: o objetivo da página é direct response, quanto menos cliques e menos telas intermediárias entre o anúncio e o checkout, melhor a taxa de conversão tende a ser. Um carrinho nativo, com etapa de "revisar carrinho" antes do checkout, adiciona fricção que não interessa nesse tipo de funil. Também dá controle total sobre o design de cada seção de oferta, já que nada depende de componentes prontos de um plugin.
A alternativa: Frameship
Existe um plugin chamado Frameship (Framer Marketplace, por Insert Frame) que faz uma integração de verdade entre Framer e Shopify, via Storefront API. Ele sincroniza produtos, preços e estoque automaticamente com a CMS do Framer, e oferece componentes prontos de "adicionar ao carrinho", carrinho lateral, e checkout, tudo já conectado e funcional, sem precisar montar link de carrinho manualmente.
A diferença real: o Frameship entrega uma experiência de ecommerce completa e nativa (a pessoa adiciona produtos ao carrinho, vê o carrinho, ajusta quantidade, tudo dentro da própria LP, sincronizado ao vivo com o estoque e preço do Shopify). É a escolha certa pra uma loja de catálogo, com múltiplos produtos, onde a pessoa provavelmente quer navegar, comparar, montar um carrinho com mais de um item.
Por que não usei: não precisava dessa experiência completa, e cada etapa de carrinho nativo é uma etapa a mais entre o clique no anúncio e o checkout, o oposto do que uma LP de página única, produto único, quer otimizar. Prefiri manter controle total do funil (poucos cliques até o checkout abrir) a ganhar a conveniência de não montar os links manualmente. Se seu cenário for parecido com o meu (LP de produto único ou poucos produtos, foco em reduzir fricção até o checkout), a abordagem deste guia costuma servir melhor. Se for uma loja de catálogo maior, vale considerar o Frameship antes de partir pra essa abordagem manual.
Uma seção de oferta na LP, construída como um único componente do Framer com várias Variantes nomeadas (uma pra cada combinação de opção do produto, tipo sabor e tamanho de pack). Dois seletores trocam qual variante está ativa, e o botão final de compra dentro de cada variante já carrega o link direto pro carrinho do Shopify daquela combinação específica, sem passar por nenhuma etapa de carrinho intermediária na própria LP.
Ou seja, o funil inteiro depende de um clique só, e esse clique precisa carregar produto, valor, e atribuição de campanha, tudo junto, sem que o cliente perceba fricção nenhuma.

A primeira armadilha é achar que dá pra tratar o botão como um link fixo. Ele não é. Quando a pessoa troca sabor ou pack, o Framer desmonta a subárvore da variante antiga e monta a nova, o que significa que o elemento de link pode literalmente deixar de existir e ser substituído por outro nó, com outro href.
Se você anexa um listener de clique direto no elemento (como normalmente se faria), ele para de funcionar assim que a pessoa troca a seleção, porque o nó que você bindou não existe mais.
Solução: delegação de eventos. Em vez de escutar cliques em cada botão individual, escuto clique no document inteiro e verifico se o alvo do clique bate com o seletor do botão de checkout (e.target.closest('a[href*="dominio-do-checkout"]')). Isso funciona não importa quantas vezes o Framer remonte o nó, porque o listener não está preso a um elemento específico, está preso ao documento.
