Página de Landing Page de App com SEO
Fluxo de trabalho completo para transformar a listagem de um app na loja em um site de alta conversão e otimizado para SEO, com páginas de guia de palavras-chave de cauda longa. Stack padrão: Vite + React com pré-renderização em tempo de build (arquitetura na Fase 3). Se o repositório já tiver um framework web (Next.js, Astro), construa dentro dele e adapte os caminhos de saída. Cada fase termina com verificação.
Esta skill depende da skill gpt-image instalada separadamente e incluída no mesmo repositório. Quando forem necessárias imagens de guia, carregue essa skill e siga suas instruções. Não presuma que seu helper reside dentro do diretório desta skill.
Fase 1 — Obter a listagem da loja (fonte da verdade)
-
Busque os metadados completos da API iTunes Lookup (sem autenticação):
curl -s "https://itunes.apple.com/lookup?id=<APP_ID>&country=us"Extraia: nome, bundleId, descrição, preço/termos de compra no app, gêneros, número de avaliações, capturas de tela, ícone, versão, vendedor. Verifique também a listagem no Google Play (
play.google.com/store/apps/details?id=<bundleId>) — não presuma que seja apenas iOS. -
Baixe os assets em alta resolução reescrevendo o sufixo do thumbnail mzstatic:
- Ícone: substitua
512x512bb.jpgpor1024x1024bb.png - Capturas de tela: substitua
392x696bb.jpgpor1284x2282bb.png(com fallback suave; verifique comfile)
- Ícone: substitua
-
Leia cada captura de tela com a ferramenta Read. As legendas, tópicos do guia e texto da página de destino devem descrever o que as telas realmente mostram. Extraia também a paleta de cores e o estilo tipográfico delas.
-
Escreva
app.mdna raiz do repositório: tabela de identidade, descrição textual, lista de recursos derivada da listagem + capturas de tela, manifesto de assets, depois a pesquisa de palavras-chave (Fase 2) e o mapa de posicionamento. Este arquivo é o contrato para tudo que se segue.
Fase 2 — Pesquisa de palavras-chave que convertem
- Se as ferramentas MCP do
astroestiverem conectadas, useget_keyword_suggestionsesearch_app_storepara popularidade/dificuldade e rank atual da App Store. Registre onde o app está ranqueado hoje. - Use o WebSearch para validar caudas longas do lado Google (a página de destino ranqueia no Google, não na App Store).
- Estruture a saída em
app.md:- Palavras-chave primárias (3–5 termos principais) → tag title, H1, texto do herói, meta description
- Secundárias → H2s das seções, texto dos recursos
- Cauda longa (6–10 frases de pergunta/tarefa) → uma página de guia para cada
- Regras importantes:
- Cada cauda longa deve mapear para uma dor que o app resolva de forma demonstrável — idealmente visível em uma captura de tela. É isso que faz o tráfego converter.
- Verifique o SERP real para cada termo principal e ignore os poluídos (ex.: "rastreador de ações" retorna apps do mercado de ações; "software de gestão de estoque" retorna fornecedores empresariais).
- Prefira frases de "como fazer" onde blogs ranqueiam — uma página de app com schema HowTo/FAQ pode vencê-los.
Fase 3 — SEO na página da landing page
Arquitetura Vite + React SSG (padrão)
Um SPA é invisível para crawlers sem renderização JS, portanto, entregue HTML estático pré-renderizado. Nenhum framework SSG é necessário — um script de pré-renderização de ~30 linhas resolve, e as páginas geralmente precisam de zero JS no cliente (acordeões de FAQ são <details> nativos; não hidrate o que não tem interatividade):
landing/
package.json # build: vite build --ssr src/entry-server.tsx --outDir dist-ssr && node scripts/prerender.mjs
vite.config.ts # plugins: [react()], ssr: { noExternal: true } ← compila react em dist-ssr para que prerender.mjs o importe de forma independente
index.html # shell apenas para dev: <div id="root"> + /src/entry-client.tsx
public/ # style.css, assets/ (copiado diretamente para dist/)
src/
data.ts # TODO o conteúdo: entradas de FAQ, corpos de guia, títulos, descrições. Fonte única da verdade.
seo.ts # Tipo PageMeta + construtores de JSON-LD (homeJsonld, guideJsonld, breadcrumbJsonld) lendo de data.ts
components.tsx # Header, Footer, StoreBadge, FaqItem, GuideCard, CtaCallout
pages/ # Home.tsx, GuidePage.tsx, GuidesIndex.tsx
routes.tsx # ROTAS: [{ meta: PageMeta, element }] — uma entrada por página, guias distribuídos a partir de data.ts
entry-server.tsx # renderRoute(route): string HTML completo — tags head + JSON-LD + renderToStaticMarkup(body)
entry-client.tsx # apenas dev: matchRoute(location.pathname) → createRoot().render()
scripts/prerender.mjs # importa dist-ssr/entry-server.js; escreve dist/<path>/index.html por rota + sitemap.xml + robots.txt; cpSync public/ → dist/
Decisões importantes incorporadas nesta estrutura:
renderToStaticMarkup, nãorenderToString— sem marcadores de hidratação, HTML limpo, já que nenhum pacote do cliente é enviado.- URLs limpas: caminhos de rota terminam em
/(/guides/<slug>/) e o pré-renderizador escreve<path>/index.html. Links internos são absolutos do site (/guides/…/), o que também faz a navegação do servidor de desenvolvimento funcionar. - Experiência de desenvolvimento:
viteserveentry-client.tsxcom HMR; a entrada do cliente nunca é enviada para produção. esc()valores de atributo no modelo head construído manualmente; JSON-LD viaJSON.stringify(sem problemas de escape).- O atributo React é
fetchPriority(camelCase) —fetchpriorityminúsculo gera aviso.
Regras on-page (qualquer stack)
Seções: herói, download, capturas de tela, como funciona, guias, FAQ, CTA, rodapé.
- Exatamente um H1, contendo a palavra-chave primária. Títulos de seção são H2 (títulos do tipo "Disponível em" não devem ser H1s).
<title>≈ "Marca — Palavra-chave Primária para Público" (≤60 caracteres). Meta description ≤155 caracteres com palavra-chave primária e principais diferenciais.- URL canônica por página, OG + Twitter cards, meta
apple-itunes-app(banner inteligente do app). Na configuração Vite, eles estão ementry-server.tsx; Next.js:metadataBase,alternates.canonical, títulotemplate,itunes.appId. - JSON-LD na página inicial:
SoftwareApplication(comoffers,installUrl; puleaggregateRatingcom menos de ~50 avaliações),FAQPage,WebSite. Construa os objetos emseo.tsa partir dedata.tspara que o schema e o texto visível compartilhem uma fonte. - Badges de loja/CTA de download acima da dobra, mais uma seção de CTA repetida abaixo.
- Capturas de tela recebem texto
altcom palavras-chave descrevendo a tela real. Recompacte PNGs da loja (muitas vezes 1–2 MB cada) para JPEGs de ≤200 KB (sips -Z 1386 -s format jpeg -s formatOptions 80); mantenha os originais empublic/assets/full/. - FAQ: 8–10 perguntas, cada uma uma consulta de pesquisa real, respondidas em 2–3 frases, cada uma com um link "Saiba mais →" para seu guia correspondente. O JSON-LD FAQPage deve conter o mesmo texto Q/A que o FAQ visível — ambos renderizados a partir do mesmo array de
data.ts. sitemap.xml+robots.txt: gerados porscripts/prerender.mjsa partir da lista ROUTES, para que novos guias apareçam automaticamente.
Fase 4 — Páginas de guia (uma por palavra-chave de cauda longa)
Armazene o conteúdo do guia em um único módulo de dados (src/data.ts na configuração Vite; lib/guides.ts no Next.js) e renderize por meio de um único componente de modelo, de modo que o schema, cards, links de rodapé e sitemap derivem todos da mesma lista. Modele cada guia como dados estruturados, não como blocos HTML: { slug, title, description, h1, intro, featureImage: { src, alt, width, height }, howto?, sections: [{ h2, paras, cta?, figure? }], faq, related } — a chamada CTA e as figuras tornam-se componentes, e os parágrafos permanecem strings pesquisáveis (HTML inline <em> via dangerouslySetInnerHTML é aceitável).
Fluxo de trabalho de imagem de recurso GPT Image
Cada artigo de guia recebe sua própria imagem de recurso paisagem. Carregue e use a skill gpt-image, que chama o gpt-image-2 da OpenAI; não substitua por imagens de stock, gradientes CSS, capturas de tela ou outro modelo de imagem, a menos que o usuário peça explicitamente. Se gpt-image não estiver instalado, pare antes da geração de imagens e informe ao usuário para instalar a skill irmã deste repositório.
- Após os títulos e slugs dos guias estarem finalizados, faça um breve resumo de imagem por guia a partir de sua intenção de pesquisa, assunto concreto e a identidade visual do app capturada em
app.md. Os conceitos devem ser significativamente diferentes, não trocas de paleta de uma mesma composição. - Solicite uma imagem de recurso editorial na paleta de cores do app. Descreva o assunto, cenário, composição, iluminação, materiais, câmera/ponto de vista e onde deve ficar o espaço visual de respiro. Termine cada prompt com:
Imagem de recurso editorial paisagem, composição 3:2. Absolutamente sem texto, palavras, letras, números, legendas, marcas d'água, rótulos de interface ou logotipos.Não peça ao modelo para renderizar o título do artigo. - Resolva
GPT_IMAGE_SKILL_DIRpara o diretório instalado contendo oSKILL.mdda skillgpt-image, então execute seu gerador com um destino determinístico:Isso produz uma fonte paisagem de 1536×1024. Crie o diretório de destino quando necessário. Preserve a fonte gerada; use o pipeline de imagem do framework para variantes responsivas menores, em vez de recompactá-la repetidamente."$GPT_IMAGE_SKILL_DIR/scripts/generate_image.py" "<prompt específico do guia>" \ --model gpt-image-2 \ --aspect-ratio 3:2 \ --quality high \ --background opaque \ --format webp \ --output "<diretório-público-do-site>/assets/guides/<slug>-feature.webp" - Inspecione cada imagem em tamanho real antes de conectá-la. Verifique se há texto/símbolos acidentais, objetos malformados, UI do app copiada, logotipos não intencionais, assunto irrelevante e baixa segurança de corte nas proporções de desktop e card. Regere apenas as imagens com falha, alterando o prompt para abordar o defeito observado; pare após duas regenerações com falha para o mesmo guia e relate o problema restante em vez de gastar tempo indeterminadamente.
- Adicione a imagem ao registro estruturado do guia com
width: 1536,height: 1024e texto alt descritivo conciso baseado no que a imagem realmente contém. Renderize-a como a imagem de recurso acima da dobra do artigo, a miniatura do card do guia e aog:image/twitter:imageda página. Adicione-a ao JSON-LDArticle.imagecomo URL absoluta. Não use a palavra-chave de pesquisa como texto alt genérico quando ela não descrever os pixels.
Por guia:
- Slug da URL = a palavra-chave (
/guides/how-to-keep-track-of-inventory-small-business) - Abertura com resposta em primeiro lugar: o primeiro parágrafo responde diretamente à pergunta pesquisada (isca para featured snippet), depois o corpo ensina a tarefa com o app inserido como a ferramenta — ensine primeiro, venda depois.
- H2s carregam frases secundárias da palavra-chave. 600–900 palavras de conteúdo substancial, sem enrolação.
- Uma captura de tela relevante do app com legenda descritiva, uma chamada CTA no meio da página e uma FAQ de 2 perguntas exclusiva daquele guia (não duplique perguntas da FAQ da página inicial — duplicação de schema).
- JSON-LD:
Article+BreadcrumbList+FAQPage, maisHowToquando o guia tiver formato de passos. - Faça links cruzados entre guias e de volta às seções da página inicial.
- O asset de imagem de recurso gerado pelo GPT Image está presente, é único para o artigo e está conectado ao herói, card, metadados sociais e JSON-LD
Article.image. Usesrcsetresponsivo/otimização de imagem do framework e defina dimensões explícitas para evitar layout shift; não faça lazy-load da imagem de recurso acima da dobra.
Fase 5 — Despoluir o texto (Wikipedia: Sinais de escrita de IA)
Execute esta passagem em TODO o conteúdo que você escreveu (guias, respostas de FAQ, texto do herói/seções) antes de enviar. Os sinais, em ordem de destaque:
- Travessões — o sinal nº 1. Orçamento: um punhado em todo o site, não por parágrafo. Substitua por pontos, vírgulas, dois-pontos, parênteses.
- Paralelismos negativos — "Não é X, é Y", "não apenas X mas Y", "X, não Y". No máximo um por site, e apenas se merecer seu lugar.
- Regra de três — "sem A, sem B, sem C", "adj, adj, adj". Quebre em pares ou listas reais.
- Estrutura formulaica — aberturas idênticas entre páginas (ex.: todo guia começando com o mesmo modelo de tese em negrito). Varie: resposta direta, cenário, afirmação simples.
- Cadência uniforme e incisiva — frase após frase curta com impacto. Varie o comprimento das frases; deixe algumas frases apenas carregarem informações.
- Lista negra de vocabulário: mergulhar, tapeçaria, testemunho, fundamental, crucial, vibrante, contínuo (seamless), sem esforço, ostenta, alavancar, elevar, robusto, meticuloso, cenário, sublinhar, exibir, fomentar, transformador, revolucionário, capacitar, otimizar, "recurso matador", "fonte única da verdade", "com confiança", repetido "Aqui está como/Aqui está o...".
- Evitação de cópula — "serve como", "se coloca como", "representa" onde "é" funciona. Use "é".
- Particípios de análise superficial — orações "...destacando", "...sublinhando", "...refletindo" presas aos finais de frases.
- Substitua aforismos por especificidades concretas (um preço, um mês, um objeto nomeado). Especificidades parecem humanas; generalidades parecem geradas.
Verificação mecânica (adaptar caminhos):
grep -o "—" <arquivos de conteúdo> | wc -l # alvo: dígitos únicos em todo o site
grep -inE "delve|tapestry|testament|pivotal|crucial|vibrant|seamless|effortless|boasts|leverage|elevate|robust|meticulous|landscape|underscore|showcas|foster|transformativ|game.chang|revolutioniz|empower|streamlin|serves as|stands as|it's not just|isn't just|not only" <arquivos de conteúdo>
Nomes de classe CSS (ex.: transition-transform) gerarão falsos positivos; ignore-os. O que você mantiver deve sobreviver à pergunta "um ser humano ocupado escreveria esta frase?"
Mantenha intacto durante a despoluição: slugs, cabeçalhos/palavras-chave, links internos, schema (regere o schema a partir da fonte reescrita para que o texto visível e o JSON-LD permaneçam idênticos).
Fase 6 — Verificar
npm run builddeve passar, então execute uma verificação com script sobredist/**/index.html: exatamente um H1 por página, canônico presente, cada<script type="application/ld+json">é analisado, cada href/src interno resolve para um arquivo em dist (mapeie URLs com barra final para<path>/index.html), cada<loc>do sitemap mapeia para um arquivo real, e as perguntas visíveis do FAQ da página inicial são iguais aosnames do JSON-LD FAQPage.- Verifique se cada registro de guia tem uma imagem de recurso paisagem distinta, se cada arquivo existe na saída compilada, se as dimensões intrínsecas são maiores em largura do que altura, se os atributos HTML width/height correspondem à origem e se as URLs Open Graph, Twitter e
Article.imagede cada guia resolvem...
[truncado para tradução]