# DataFirefly All in One SEO: documentação completa

> Documentação completa do módulo DataFirefly All in One SEO para PrestaShop 8 e 9: instalação, modelos de meta, esquemas JSON-LD, mapa do site XML, redirecionamentos, monitorização de 404, robots.txt, seguimento GA4/GTM e analisador de conteúdo.

- Página: <https://www.datafirefly.com/pt/documentation/dfallinoneseo/>
- Idioma: pt
- Atualizado em: 2026-09-09
- Outros idiomas: [fr](https://www.datafirefly.com/documentation/dfallinoneseo/index.md), [en](https://www.datafirefly.com/en/documentation/dfallinoneseo/index.md), [es](https://www.datafirefly.com/es/documentation/dfallinoneseo/index.md), [de](https://www.datafirefly.com/de/documentation/dfallinoneseo/index.md), [it](https://www.datafirefly.com/it/documentation/dfallinoneseo/index.md), [pl](https://www.datafirefly.com/pl/documentation/dfallinoneseo/index.md), [nl](https://www.datafirefly.com/nl/documentation/dfallinoneseo/index.md)
- Índice: <https://www.datafirefly.com/pt/documentation/llms.txt>

Suíte SEO premium tudo-em-um para PrestaShop 8 e 9: modelos de meta dinâmicos, esquemas JSON-LD completos, mapa do site XML multi-idioma, redirecionamentos, monitorização de 404, Open Graph e Twitter Cards, GA4 e GTM, robots.txt inteligente com bloqueio dos crawlers de IA e analisador de conteúdo, tudo num só módulo.

## Pré-requisitos

- **PrestaShop**: 8.0 a 9.x
- **PHP**: 8.1 ou superior (8.2 e 8.3 recomendados)
- **MySQL**: 5.7+ ou MariaDB 10.3+
- **Módulo productcomments** (oficial do PrestaShop): opcional, necessário apenas para o AggregateRating nos produtos
- **mod_rewrite** ativo no servidor Apache (ou equivalente em Nginx), para os URL reescritos

O módulo conhece nativamente o contexto multiloja: todas as tabelas são delimitadas por `id_shop`. Pode ter configurações completamente diferentes em cada loja.

## Instalação

1. Descarregue o ficheiro `dfallinoneseo-vX.Y.Z.zip` a partir da sua conta de cliente DataFirefly.
2. Inicie sessão no back-office do PrestaShop.
3. Vá a **Módulos → Gestor de módulos**.
4. Clique em **Carregar um módulo**, no canto superior direito.
5. Arraste o ficheiro ZIP ou clique em **Selecionar um ficheiro**.
6. A instalação cria automaticamente as 11 tabelas SQL, regista os hooks e acrescenta o menu **Melhorar → DataFirefly SEO**.

Depois da instalação, abra o **Painel** do módulo, para uma vista do resultado SEO global e dos pontos a corrigir prioritariamente.

## Primeira configuração em 10 minutos

Este percurso rápido permite-lhe configurar o essencial antes do primeiro rastreio do Google.

1. **Definições → Geral**: ative o módulo, preencha o nome do site e a designação de «Início» para a navegação estruturada.
2. **Meta e modelos**: defina, no mínimo, um modelo de _Produto_ e um modelo de _Categoria_ (ver a secção dedicada).
3. **Schema → Identidade da organização**: preencha logótipo, telefone, e-mail, morada e URL das redes sociais (`sameAs`).
4. **Mapa do site**: ative-o e clique em **Gerar agora**.
5. **Seguimento**: acrescente o seu Measurement ID do GA4 e/ou o ID do GTM.
6. **Seguimento → Verificações**: cole o valor de verificação da Google Search Console.
7. **Robots.txt**: clique em **Carregar as predefinições (PS + bloqueio de IA)**, para partir de uma base saudável.

## Modelos de meta

O módulo substitui o preenchimento manual de `meta_title` e `meta_description` por modelos dinâmicos por tipo de entidade. Ao gravar uma ficha com as meta vazias, é aplicado automaticamente o modelo correspondente.

### Tipos de entidade suportados

- **Produto**: fichas de produto (de todos os tipos, incluindo virtuais e packs)
- **Categoria**: páginas de categoria
- **Página CMS**: páginas de conteúdo estático
- **Marca / Fabricante**: páginas de fabricante
- **Fornecedor**: páginas de fornecedor
- **Início**: página inicial da loja
- **Páginas genéricas**: `/contact`, `/sitemap` e outras

### Tokens disponíveis

Os tokens são substituídos pelos valores reais na apresentação da página. Nem todos os tokens estão disponíveis em todos os tipos de entidade.

- `{shop_name}`: nome da loja
- `{sep}`: separador (por predefinição, `|`)
- `{product_name}`: nome do produto (idioma atual)
- `{product_reference}`: referência interna
- `{product_sku}`: alias da referência
- `{product_ean13}`: código de barras EAN13
- `{product_brand}`, `{brand}`: marca ou fabricante
- `{category}`: categoria predefinida (produto) ou nome da categoria (página de categoria)
- `{category_parent}`: nome da categoria mãe
- `{category_description}`: descrição curta (máximo de 160 caracteres)
- `{short_description}`: descrição curta do produto (máximo de 160 caracteres)
- `{price}`: preço com IVA, formatado com a moeda
- `{price_tax_excl}`: preço sem IVA, formatado
- `{title}`: título da página CMS
- `{summary}`: extrato do conteúdo CMS (máximo de 160 caracteres)

### Blocos condicionais

Para não mostrar um token vazio, use a sintaxe condicional:

```
{?product_brand}{product_brand} | {/?}{product_name} - {shop_name}
```

Se `product_brand` estiver vazio (produto sem marca), todo o bloco entre `{?token}` e `{/?}` é removido. Caso contrário, o conteúdo é apresentado e os tokens lá dentro são substituídos normalmente.

### Exemplos de modelos recomendados

**Produto**:

```
Title: {?product_brand}{product_brand} {/?}{product_name} - {category} | {shop_name}
Description: Descubra {product_name}{?product_brand} da {product_brand}{/?}. {short_description} Entrega rápida na {shop_name}.
```

**Categoria**:

```
Title: {category} - {?category_parent}{category_parent} - {/?}{shop_name}
Description: Todos os produtos da categoria {category} na {shop_name}. {category_description}
```

**Início**:

```
Title: {shop_name} - Loja online
Description: Bem-vindo à {shop_name}. Descubra o nosso catálogo, com entrega rápida e pagamento seguro.
```

Cuidado com o comprimento em português: um título traduzido do francês ou do inglês fica em regra 10 a 20 % mais longo, e o Google corta por volta dos 60 caracteres. Depois de definir os modelos, verifique a pré-visualização SERP num produto de nome comprido antes de os aplicar em massa. E atenção às promessas: «entrega rápida» ou «o melhor preço» num modelo aplicado a todo o catálogo tem de corresponder à realidade, sob pena de cair no Decreto-Lei n.º 57/2008 sobre práticas comerciais desleais.

### Substituição por entidade

Para substituir uma ficha específica (por exemplo, um produto emblemático), clique no ícone **Substituição de meta** no menu **Edição em massa**, ou use o URL:

```
?controller=AdminDfSeoMeta&entity=product&entity_id=42
```

A página de substituição permite definir `meta_title`, `meta_description`, a diretiva robots (`noindex,follow`, por exemplo) e um canonical personalizado, por idioma.

A diretiva robots definida numa entidade específica tem prioridade sobre as definições globais de indexação. Use-a com parcimónia, para não desindexar por acidente as suas melhores páginas.

## Esquemas JSON-LD

O módulo gera um bloco `@graph` único, que reúne todos os esquemas da página atual, validado no Rich Results Test do Google.

### Esquemas gerados automaticamente

- **Organization**: em todas as páginas, com a identidade da empresa
- **WebSite**: na página inicial, com `SearchAction` para ativar a caixa de pesquisa nos sitelinks
- **LocalBusiness**: se estiver preenchida uma morada física
- **BreadcrumbList**: navegação estruturada
- **Product**: nas fichas de produto, com `offers`, `priceValidUntil`, `gtin13`/`isbn`/`mpn`
- **AggregateRating**: agregada a partir do módulo oficial productcomments
- **Article**: nas páginas CMS
- **FAQPage**: a partir dos blocos de FAQ de produto ou de página

### Identidade da organização

Separador **Schema → Identidade da organização**. Campos a preencher:

- **Tipo**: Organization, Corporation, LocalBusiness, Store, OnlineStore, OnlineBusiness
- **Logótipo**: URL absoluto (recomendado 600x60 no mínimo, em proporção quadrada ou horizontal)
- **Telefone** e **E-mail**: usados em `contactPoint`
- **Morada postal**: rua, código postal, localidade e país (ISO-2)
- **sameAs**: um URL por linha (Facebook, Instagram, LinkedIn, Twitter/X e outros)

No código postal, use o formato português com quatro dígitos, hífen e três dígitos (por exemplo, 1000-001). No país, indique `PT` em ISO-2. Se vende a partir de uma morada física aberta ao público, o tipo Store ou LocalBusiness dá-lhe acesso a resultados enriquecidos locais que o tipo Organization não dá.

### Validade das ofertas de produto

O campo _Validade das ofertas de produto (dias)_ controla o valor de `priceValidUntil` em `Product.offers`. Por predefinição, são 60 dias. O Google exige este campo para mostrar o preço nos resultados enriquecidos.

### Esquemas personalizados

Separador **Schema → Esquemas personalizados**. Permite acrescentar blocos JSON-LD à medida (HowTo, Recipe, Event, JobPosting, VideoObject, Course e outros) num âmbito preciso:

- **global**: todas as páginas
- **home**: apenas a página inicial
- **product**: todas as páginas de produto
- **product_id**: um produto concreto (usa o campo de ID)
- **category**, **category_id**: o mesmo para categorias
- **cms**, **cms_id**: o mesmo para páginas CMS

Variáveis disponíveis no JSON personalizado: `{shop_name}`, `{base_url}`, `{entity_id}` e `{entity_type}`.

O JSON-LD personalizado é inserido tal como está no `@graph`. Valide-o com o [Rich Results Test](https://search.google.com/test/rich-results) antes de publicar. Um JSON inválido é rejeitado silenciosamente.

## Mapa do site XML

O módulo gera um mapa do site XML conforme à [especificação sitemaps.org](https://www.sitemaps.org/protocol.html), com hreflang em cada URL e suporte de imagens. A arquitetura é a de um _índice de mapa do site_ por loja, e depois um mapa por tipo de entidade e por idioma, dividido em blocos.

### Configuração

Separador **Mapa do site**. Ative-o e assinale depois o conteúdo a incluir:

- Produtos (por predefinição, todos os produtos ativos)
- Categorias
- Páginas CMS
- Marcas / Fabricantes
- Fornecedores
- Imagens (acrescenta `image:image` a cada URL de produto)
- Vídeos (se existirem nas fichas)

Opções adicionais:

- **Excluir as ruturas**: retira os produtos sem stock
- **Gzip**: gera também as variantes `.xml.gz` (reduz 5 a 10 vezes o tamanho descarregado pelos crawlers)
- **URL por ficheiro**: dimensão do bloco (recomendado entre 5000 e 10000, com um máximo de 50000 por especificação XML)

### Nova geração

A geração é manual, a partir do back-office, para evitar carga imprevista no servidor. Clique em **Gerar agora**.

Para automatizar, agende um cron que chame o script seguinte (de 6 em 6 ou de 12 em 12 horas, conforme a frequência de atualização do seu catálogo):

```
0 */6 * * * php /var/www/html/index.php fc=module&module=dfallinoneseo&controller=sitemap&action=rebuild
```

### Submissão aos motores

Clique em **Notificar os motores** para avisar o Google e o Bing (endpoints antigos, mas ainda ativos). Para a Google Search Console, submeta o URL do índice do mapa do site uma vez por todas em GSC → Sitemaps. A GSC volta a rastrear automaticamente a cada alteração.

URL do índice do mapa do site: `https://a-sua-loja.pt/sitemap.xml`

## Mapa do site HTML público

É gerado automaticamente um mapa do site em HTML, legível por pessoas, em `/plan-du-site`. Agrega categorias (em árvore), páginas CMS, marcas, fornecedores e os 200 produtos mais recentes. É útil para as ligações internas e para a acessibilidade.

Este caminho vem em francês tal como é fornecido. Numa loja portuguesa, mude-o para `/mapa-do-site` nas definições de SEO antes de o URL ser indexado.

## Redirecionamentos

O módulo trata os redirecionamentos HTTP 301 (permanente), 302 (temporário), 307, 308 e 410 (Gone), com três tipos de correspondência.

### Tipos de correspondência

- **Exata**: o URL de origem tem de corresponder exatamente (sem a query string)
- **Prefixo**: o URL de origem é um prefixo do URL pedido. O sufixo é conservado no destino se a opção _Conservar a query string_ estiver assinalada. É útil para migrar pastas inteiras (`/pasta-antiga/` para `/pasta-nova/`).
- **Regex**: expressão regular do PHP (modo `~...~i`, sensível ou insensível a maiúsculas). Os grupos de captura ficam disponíveis no destino através de `$1`, `$2` e assim por diante.

### Criação manual

Separador **Redirecionamentos → Novo redirecionamento**. Campos:

- **URL de origem**: caminho sem o domínio (por exemplo, `/pagina-antiga`)
- **URL de destino**: caminho ou URL absoluto. Deixe vazio para um código 410.
- **Tipo de correspondência**, **Código HTTP** e **Conservar a query string**

### Importação e exportação CSV

Formato CSV esperado (com cabeçalho):

```
source,destination,type,code
/produto-antigo,/produto-novo,exact,301
/pasta-antiga/,/pasta-nova/,prefix,301
/old-(.*),/new-$1,regex,301
```

A exportação CSV retoma os redirecionamentos que estiverem filtrados na lista.

### Redirecionamento automático na mudança de slug

Se a opção **Definições → Monitorização → Redirecionamento 301 automático em caso de mudança de URL** estiver assinalada, o módulo cria uma 301 automaticamente quando altera o slug de um produto, de uma categoria, de uma página CMS, de uma marca ou de um fornecedor. O `created_by` fica então marcado como `auto:urlchange`, para distinção.

Esta opção evita a maioria das 404 clássicas de SEO ligadas a remodelações de conteúdo. Ative-a logo na instalação.

É especialmente útil quando traduz uma loja: mudar o slug francês de uma categoria para a versão portuguesa cria a 301 sozinho, sem perder o histórico da página. Note, porém, que os slugs portugueses devem ser escritos sem acentos (`promocoes` e não `promoções`), como é convenção no PrestaShop.

## Monitorização de 404

Separador **Monitor 404**. Capta todos os URL com erro 404 servidos pelo PrestaShop, com eliminação de duplicados, contagem de acessos, deteção de robôs e hash dos endereços IP (com o sal `COOKIE_KEY` do PrestaShop, para conformidade com o RGPD).

### Filtros disponíveis

- **Por resolver**: URL sem redirecionamento que os cubra (vista predefinida)
- **Resolvidas**: URL para os quais foi criado um redirecionamento depois
- **Robôs**: acessos vindos de user-agents identificados como robôs
- **Todas**

### Criar um redirecionamento com um clique

Em cada linha, o botão **Redirecionar** abre um formulário embutido, que preenche previamente a origem. Introduza o destino, escolha o código HTTP e confirme. A 404 é automaticamente marcada como resolvida.

### Limpeza e manutenção

O menu **Definições → Monitorização** expõe um limite de _Número máximo de entradas 404 conservadas_ (5000 por predefinição). Acima disso, o botão **Limpar as 404 antigas** elimina as entradas por resolver mais antigas.

O endereço IP é guardado sob a forma de hash, o que reduz muito o risco, mas continua a ser um dado pessoal na aceção do RGPD enquanto permitir singularizar um visitante. Fixe um limite de conservação razoável e inscreva este tratamento no seu registo de atividades, sob supervisão da CNPD.

## Robots.txt dinâmico

O módulo serve um ficheiro `/robots.txt` gerado dinamicamente a cada pedido, com base nas regras definidas em **Robots.txt**.

### Predefinições do PrestaShop e bloqueio de IA

O botão **Carregar as predefinições (PS + bloqueio de IA)** substitui todas as regras atuais e carrega uma predefinição saudável, que:

- Bloqueia os diretórios sensíveis do PrestaShop (`/admin*/`, `/cache/`, `/classes/` e outros)
- Bloqueia as páginas técnicas (`/cart`, `/order`, `/my-account` e outras)
- Bloqueia os principais crawlers de IA que não respeitam as regras: **GPTBot**, **ClaudeBot**, **CCBot**, **Google-Extended** e **anthropic-ai**
- Aponta para o mapa do site (`Sitemap: /sitemap.xml`)

Distinga os robôs que recolhem dados para treino dos agentes que respondem a uma pergunta de um utilizador em tempo real e citam a fonte. Bloquear os primeiros protege o seu conteúdo; bloquear os segundos retira-lhe visibilidade num canal em crescimento. A predefinição é conservadora: ajuste-a conforme a sua estratégia.

### Regras personalizadas

Cada regra tem um user-agent, uma diretiva (`Allow`, `Disallow`, `Crawl-delay`), um valor e uma posição (ordem no ficheiro). Ative e desative uma regra sem a eliminar, através do interruptor.

### Pré-visualização em direto

O bloco **Pré-visualização do ficheiro gerado**, no fundo da página, mostra o robots.txt tal como será servido, antes da publicação.

## Ficheiro llms.txt nativo

O módulo serve um ficheiro `/llms.txt` conforme à [especificação llmstxt.org](https://llmstxt.org/). Este ficheiro lista, em markdown, as secções principais do site, para os crawlers de IA respeitadores que preferem uma vista estruturada a recolher todo o HTML.

Não é preciso qualquer configuração: o módulo gera automaticamente o ficheiro a partir da sua árvore de categorias, páginas CMS e marcas.

## Open Graph e Twitter Cards

Separador **Social**. O módulo injeta as etiquetas `og:*` e `twitter:*` em todas as páginas.

### Definições

- **Ativar Open Graph e Twitter Cards**: interruptor principal
- **og:locale automático**: calculado a partir do idioma do contexto (por exemplo, `pt_PT`)
- **Imagem OG predefinida**: URL absoluto de uma imagem 1200×630 (usada quando a página não tem imagem própria)
- **og:site_name** e **og:type** predefinidos
- **@handle do Twitter** e tipo de cartão (`summary` ou `summary_large_image`)
- **fb:app_id**: App ID do Facebook

Nas fichas de produto, o módulo usa automaticamente a imagem principal da ficha. Nas restantes páginas, é usada a imagem OG predefinida se não estiver definida qualquer imagem.

## Seguimento: GA4, GTM e pixéis

### GA4 e Enhanced Ecommerce

Campo **GA4 Measurement ID**: formato `G-XXXXXXXXXX`. Validação automática do formato.

Assinale **Enhanced Ecommerce** para ativar os eventos `view_item`, `view_item_list`, `add_to_cart`, `remove_from_cart`, `begin_checkout`, `add_payment_info` e `purchase`.

Assinale **Respeitar o Consent Mode v2** para anonimizar os acessos até ao consentimento explícito (compatível com as CMP correntes).

Em Portugal, a Lei n.º 41/2004 exige consentimento prévio antes de qualquer depósito de cookies de medição ou publicitários, e o RGPD exige uma base para a transmissão de dados ao Google. Deixe o Consent Mode v2 ativo e ligue o módulo à sua plataforma de consentimento: sem isso, o GA4 dispara antes de o visitante ter escolhido, o que é precisamente o cenário que a CNPD sanciona.

### Google Tag Manager

Campo **GTM ID**: formato `GTM-XXXXXXX`. O módulo injeta o snippet do GTM no `head` e o recurso `noscript` logo a seguir à abertura do `body`.

### Pixéis publicitários

- **Facebook Pixel ID**: 15 dígitos
- **TikTok Pixel ID**: alfanumérico

Se o Consent Mode v2 estiver ativo, estes pixéis só disparam depois do consentimento.

### Verificações de propriedade

Cole os valores das etiquetas de verificação (sem a etiqueta `meta` completa, apenas o conteúdo do atributo `content`):

- Google Search Console
- Bing Webmaster Tools
- Yandex Webmaster
- Pinterest
- Baidu

### Código personalizado no head e no fim do body

Dois campos livres aceitam HTML e JS arbitrários:

- **Código injetado no head**: para scripts de terceiros e meta complementares
- **Código injetado imediatamente antes do fecho do body**: ideal para widgets de conversa, retargeting tardio e scripts assíncronos

Estes campos não fazem qualquer validação. Um erro de sintaxe de HTML pode partir a apresentação da página. Teste em pré-produção antes de publicar.

## Analisador de conteúdo

Separador **Analisador**. Submeta um produto, uma categoria, uma página CMS ou HTML em bruto ao analisador, para obter um resultado SEO global e o detalhe das métricas.

### Métricas calculadas

- **Resultado SEO global** (0 a 100): ponderação dos vários controlos
- **Legibilidade Flesch**: aproximação multi-idioma (contagem de sílabas por grupos de vogais)
- **Número de palavras** e **número de frases**
- **Densidade da palavra-chave principal** (em %)
- **Ligações internas, externas e nofollow**
- **Imagens sem atributo alt**
- **Estrutura dos títulos H1 a H6**
- Presença da palavra-chave no **slug** e no **primeiro parágrafo**

A legibilidade Flesch foi calibrada para o inglês e é apenas uma aproximação em português, onde as palavras são mais longas. Use-a para comparar dois textos seus, e não como um valor absoluto.

### Verificações

O analisador devolve uma lista de verificações com o estado `good`, `warn` ou `bad`:

- Comprimento do title (50 a 60 caracteres)
- Comprimento da meta description (140 a 160 caracteres)
- Presença e comprimento do slug
- Comprimento do corpo (mínimo de 300 palavras)
- Presença de pelo menos uma imagem com alt
- Palavra-chave no title, no primeiro parágrafo e no slug
- Densidade da palavra-chave entre 0,5 % e 2,5 %
- Pelo menos um H1 e vários H2/H3

O analisador é um guia, não uma verdade absoluta. Um resultado acima de 80 é excelente. Abaixo de 50, reveja a estrutura e a formulação. Nunca sacrifique a qualidade editorial por um número.

## Edição em massa

Separador **Edição em massa**. Grelha paginada (30 entradas por página), com filtros, para alterar rapidamente `meta_title`, `meta_description` e `link_rewrite` em produtos, categorias ou páginas CMS.

### Filtros disponíveis

- **Todas**
- **Sem title**: apenas as entradas com meta_title vazio
- **Sem description**: apenas as entradas com meta_description vazia
- **Pesquisa por nome**

### Aplicar os modelos em massa

O botão **Aplicar os modelos** aplica automaticamente o modelo definido para o tipo de entidade atual às fichas que correspondem aos filtros. Assinale **Aplicar apenas aos campos vazios** para não sobrepor as meta já preenchidas.

## Metabox de SEO na ficha de produto

Na página de edição de um produto no back-office, é acrescentado um painel **DataFirefly SEO** com:

- Um **resultado SEO em direto** (7 controlos: comprimento do title, da description, do slug e do corpo, imagem, EAN13 e marca)
- Uma **pré-visualização SERP do Google**, apresentada com fidelidade
- A palavra-chave principal detetada

## Definições avançadas

### Indexação

Separador **Definições → Indexação**:

- **hreflang multi-idioma**: gera as etiquetas `link rel="alternate"` em todas as páginas
- **Estratégia de x-default**: _Idioma predefinido_ (recomendado), _Inglês_ ou _Desativado_
- **URL canonical**: injeta `link rel="canonical"`
- **Canonical nas paginações**: _Na página atual_ (recomendado), _Sempre na página 1_ ou _Sem canonical_
- **noindex automáticos**: páginas /search, carrinho, a minha conta, novidades, mais vendidos, promoções e facetas
- **Canonical para a página mãe nas facetas**: evita o conteúdo duplicado da navegação por facetas

Numa loja com português e outro idioma, o hreflang é o que evita que o Google trate as duas versões como conteúdo duplicado. Verifique na Search Console, algumas semanas depois de ativar o português, que as duas versões estão bem emparelhadas.

### Imagens

- **Geração automática dos atributos alt**: ao gravar uma imagem sem alt, aplica o modelo
- **Modelo de alt**: por predefinição, `{product_name} - {shop_name}`
- **Lazyload nativo das imagens**: acrescenta `loading="lazy"` e `decoding="async"` a todas as imagens, com recurso ao IntersectionObserver para as imagens em `data-src`

### Manutenção

- **Limpar a cache**: purga a cache do Smarty e a cache do PrestaShop
- **Limpar as 404 antigas**: aplica o limite configurado
- **Exportar todos os dados (JSON)**: descarrega um ficheiro JSON com todas as tabelas de SEO da loja atual (útil para migrar entre ambientes ou para uma cópia de segurança antes da desinstalação)

## Multiloja

Todas as funcionalidades estão delimitadas por `id_shop`. Ao mudar de loja através do seletor de contexto do PrestaShop, vê e altera apenas os dados dessa loja.

Casos particulares a conhecer:

- **Modelos**: um modelo por par de tipo de entidade e loja. Defina explicitamente os modelos para cada loja.
- **Mapa do site**: um índice distinto por loja, acessível em `https://loja-1.pt/sitemap.xml`, `https://loja-2.pt/sitemap.xml` e assim por diante
- **Robots.txt**: regras por loja, servidas no domínio correspondente
- **Redirecionamentos**: por loja
- **Esquemas personalizados**: por loja

## Resolução de problemas

### O mapa do site não é gerado

- Confirme que a pasta `modules/dfallinoneseo/sitemaps/` é acessível para escrita pelo PHP
- Verifique as permissões: `chmod 755 modules/dfallinoneseo/sitemaps/`
- Aumente o `max_execution_time` no php.ini se tiver mais de 50 000 produtos

### Os esquemas JSON-LD não aparecem

- Confirme que o módulo está ativo (**Definições → Geral**)
- Confirme que o tipo de esquema em causa está ativo (**Schema → Tipos de esquemas gerados**)
- Limpe a cache do PrestaShop
- Inspecione o código HTML: os esquemas são injetados num bloco `script type="application/ld+json"`

### Os redirecionamentos 301 não funcionam

- Confirme que o módulo está instalado e ativo
- Confirme que os redirecionamentos estão marcados como **ativos**
- Nas regex, teste a sua expressão em [regex101.com](https://regex101.com/), em modo PCRE
- A ordem de prioridade é: exata, prefixo, regex (por `hit_count` decrescente)

### O GA4 ou o GTM não são injetados

- Verifique o formato do ID (`G-XXXXXXX` ou `GTM-XXXXXXX`)
- Se o Consent Mode v2 estiver ativo, o snippet fica em modo «denied» por predefinição até ao consentimento. Verifique a camada da CMP.
- Inspecione o `head` da página: o snippet do GA4 ou do GTM é injetado imediatamente antes do fecho

### O robots.txt não muda

- Confirme que não existe um ficheiro `robots.txt` estático na raiz do site (teria prioridade sobre o módulo). Elimine-o.
- O módulo serve o robots.txt através de uma rota do PrestaShop: confirme que os _URL reescritos_ estão ativos

### Erro na criação das tabelas SQL durante a instalação

- Confirme que o utilizador de MySQL tem permissões de `CREATE` e `ALTER`
- Verifique a codificação: o MySQL tem de suportar `utf8mb4` com a colação `utf8mb4_unicode_ci`
- Se o prefixo de tabela personalizado do PrestaShop tiver mais de 5 caracteres, alguns nomes de índice podem ultrapassar o limite de 64 caracteres do MySQL. Contacte o suporte.

## Referência técnica

### Hooks utilizados

O módulo regista 18 hooks:

- `displayHeader`: injeção das meta, canonical, hreflang, OG, Twitter, JSON-LD, GA4/GTM e verificações
- `displayBeforeBodyClosingTag`: injeção do noscript do GTM, do noscript do FB Pixel e do código personalizado de fim de body
- `displayBackOfficeHeader`: CSS e JS do back-office
- `displayAdminProductsExtra`: metabox de SEO na ficha de produto
- `actionDispatcherBefore`, `actionDispatcherAfter`: encaminhamento dos redirecionamentos e captura das 404
- `actionObjectProductAddAfter`, `actionObjectProductUpdateAfter`: preenchimento automático das meta e 301 automática
- `actionObjectCategoryAddAfter`, `actionObjectCategoryUpdateAfter`: o mesmo para categorias
- `actionObjectCmsAddAfter`, `actionObjectCmsUpdateAfter`: o mesmo para CMS
- `actionObjectManufacturerUpdateAfter`, `actionObjectSupplierUpdateAfter`: 301 automática na mudança de slug
- `actionAdminControllerSetMedia`, `actionFrontControllerSetMedia`: recursos CSS e JS
- `displayProductExtraContent`: reservado para utilizações futuras
- `moduleRoutes`: rotas `/sitemap.xml`, `/plan-du-site`, `/robots.txt` e `/llms.txt`

### Tabelas SQL acrescentadas

Todas as tabelas usam o prefixo `df_seo_`, o charset `utf8mb4` e a colação `utf8mb4_unicode_ci`:

- `df_seo_meta`, `df_seo_meta_lang`: substituições de meta por entidade
- `df_seo_template`, `df_seo_template_lang`: modelos por tipo
- `df_seo_redirect`: redirecionamentos 301/302/307/308/410
- `df_seo_404`: registo das 404
- `df_seo_score`: instantâneos de resultado (analisador)
- `df_seo_keyword`: palavras-chave principais
- `df_seo_robots_rule`: regras do robots.txt
- `df_seo_schema_custom`: esquemas JSON-LD personalizados
- `df_seo_log`: registo de diagnóstico interno

### Desinstalação

A desinstalação elimina os hooks e os separadores de back-office, mas **conserva as tabelas SQL e os dados**. Para limpar por completo:

```
DROP TABLE ps_df_seo_meta, ps_df_seo_meta_lang, ps_df_seo_template, ps_df_seo_template_lang,
           ps_df_seo_redirect, ps_df_seo_404, ps_df_seo_score, ps_df_seo_keyword,
           ps_df_seo_robots_rule, ps_df_seo_schema_custom, ps_df_seo_log;
DELETE FROM ps_configuration WHERE name LIKE 'DFSEO_%';
```

Antes de desinstalar, use **Definições → Manutenção → Exportar todos os dados (JSON)** para guardar um arquivo completo. O formato JSON permite reimportar os redirecionamentos, os modelos e os esquemas noutra instalação.

## Atualizações e suporte

- **Atualizações**: 12 meses incluídos na compra. Renovação anual opcional por 49 €.
- **Suporte**: 12 meses por e-mail, com resposta em 48 horas úteis.
- **Changelog** e transferência das últimas versões na [sua conta de cliente DataFirefly](https://www.datafirefly.com/pt/produto/all-in-one-seo-prestashop/).
