Files
claude-plugins/wordpress/skills/wp-meteor/SKILL.md
T
ealmeida c74dab4ac2 wordpress: nova skill mcp-wpmeteor (como usar o MCP wpmeteor)
- documenta as 8 tools do MCP wpmeteor: status, config, toggle de modulo,
  delay, exclusoes, telemetria detected
- wp-meteor actualizada: estado real confirmado nos 8 sites do bundle
  (so emanuelalmeida.pt tem o plugin), cross-referencia para mcp-wpmeteor
- mesma convencao de mcp-wpfc/mcp-element-pack/mcp-cloudflare-app: esta
  skill e o 'como executar', wp-meteor continua a ser o mapeamento
2026-08-19 05:35:21 +01:00

526 lines
30 KiB
Markdown

---
name: wp-meteor
description: Diagnóstico e configuração do WP Meteor (delay/reorder de JavaScript não crítico) via WP-CLI em servidores CWP e via o MCP `wpmeteor` (projecto `mcp-wpmeteor`, multi-site, 8 tools — ver skill `mcp-wpmeteor` para o "como executar"). Cobre os 5 módulos reais do plugin — `ultimate-reorder` (atraso de execução de JS até interacção do utilizador, com modo "zero delay" e modo "só interacção"), `exclude` (exclusões manuais por regex), `gdpr` (exclusões automáticas para 8 plugins de cookies), `elementor-animations` e `elementor-pp` (emulação do menu Elementor PowerPack Pro — NÃO é "Elementor Pro") — mais o módulo interno `Compatibility` (sempre activo, não configurável, com exclusões automáticas para dezenas de outros optimizadores). Cobre também os mecanismos de bypass automático (query strings, user agents, page builders, conflito com WP Rocket/Nitropack/FastPixel), o endpoint REST `wpmeteor/v1/detect`, e diagnóstico de CLS/CWV com Chrome DevTools performance trace. Usar quando "wp meteor", "wpmeteor", "atraso javascript", "delay js", "ultimate reorder", "cls alto", "layout shift", "core web vitals wordpress", "facade pattern js", "js não crítico", "elementor powerpack pro", "zero delay mode", "wpmeteordisable", "wpmeteordebug", "wpmeteor mcp".
---
# /wp-meteor — Diagnóstico e config do WP Meteor (delay de JavaScript)
Plugin de performance de terceiros (`wp-meteor`, autor Aleksandr Guidrevitch,
v`3.4.18`). Melhora TBT/INP **atrasando a execução de JavaScript não crítico**
até à primeira interacção do utilizador ou até um timeout fixo. Config
completa numa única option serializada, `wp_options.wp-meteor-settings`
(array PHP, **5 módulos reais** + versão + campo interno `detected`).
Catálogo confirmado por leitura completa do código-fonte do plugin
(5718 linhas em todos os `.php`, sessão 16-08-2026) — não há módulos
escondidos por descobrir; o que está documentado abaixo é o total.
Confirmado activo em `emanuelalmeida.pt` (16-08-2026, esta sessão). **Verificado ao vivo
19-08-2026 nos 8 sites WordPress reais do bundle Descomplicar (`wp plugin list`):
`emanuelalmeida.pt` é o ÚNICO site com o WP Meteor instalado** — `descomplicar.pt` (produção),
`starter.descomplicar.pt`, `ccv.descomplicar.pt`, `care.descomplicar.pt`,
`ecommerce-demo.descomplicar.pt`, `e-commerce.descomplicar.pt` e `ecommerce.descomplicar.pt` não
o têm. Verificar sempre por site antes de assumir que está presente.
**Gestão activa (ligar/desligar módulos, mudar delay, exclusões) via MCP:** ver skill
`mcp-wpmeteor` — MCP dedicado multi-site (`wpmeteor` em `~/.omp/agent/mcp.json`, 8 tools),
testado ponta-a-ponta contra produção 19-08-2026. Esta skill continua a ser a fonte de
conhecimento (o que cada chave significa, gotchas); a skill `mcp-wpmeteor` é o "como executar".
---
## Comandos base (SSH + WP-CLI, servidor CWP)
```bash
PATH=/home/USER/public_html # ex: /home/ealmeida/emanuelalmeida.pt
# Ler a option completa (fonte de verdade)
sudo -u USER /usr/local/bin/wp option get wp-meteor-settings --format=json --path=$PATH
# Confirmar versão e estado do plugin
sudo -u USER /usr/local/bin/wp plugin get wp-meteor --format=json --path=$PATH
# Via SSH directo (alias `server` já configurado, porta 9443)
ssh server "sudo -u USER /usr/local/bin/wp option get wp-meteor-settings --path=$PATH --format=json 2>/dev/null"
```
Os avisos PHP (`WP_DEBUG_LOG already defined`) que aparecem em `stderr` são
ruído do ambiente — ignorar, não é erro do plugin.
---
## Estrutura real da option `wp-meteor-settings` (verificado ao vivo)
```json
{
"ultimate-reorder": {
"enabled": true,
"id": "ultimate-reorder",
"delay": "2",
"description": ""
},
"gdpr": {
"enabled": true,
"id": "gdpr",
"description": "Most of the time, you want your GDPR/Cookie to be displayed instantly..."
},
"exclude": {
"enabled": true,
"id": "exclude",
"description": "Specify URLs or keywords or regular expressions... GA and GTM",
"value": []
},
"elementor-animations": { "enabled": true, "id": "elementor-animations", "description": "" },
"elementor-pp": { "enabled": true, "id": "elementor-pp", "description": "" },
"v": "3.4.18"
}
```
| Módulo | Estado real | O que faz |
|---|---|---|
| `ultimate-reorder` | `enabled=true`, **`delay=2`** (segundos, string) | Mecanismo central — ver secção seguinte |
| `gdpr` | `enabled=true` | Impede que o banner de cookies/GDPR seja atrasado — aparece instantaneamente |
| `exclude` | `enabled=true`, **`value: []` — lista vazia** | ⚠️ Lista de URLs/palavras-chave/regex a excluir do atraso. **Nada está excluído hoje.** A própria descrição da opção sugere excluir menus, carrosséis do hero, GA e GTM — nenhum destes está configurado |
| `elementor-animations` | `enabled=true` | Compatibilidade com animações nativas do Elementor (deixa correr entrance animations mesmo com scripts atrasados) |
| `elementor-pp` | `enabled=true` | ⚠️ **Não é "Elementor Pro"** — emula o menu do plugin de terceiros **Elementor PowerPack Pro** (Livemesh). Título real no código: `"Emulate Elementor Powerpack Pro menu"`. Se o site não usa PowerPack Pro, este módulo é irrelevante e pode ficar ligado sem efeito |
| `v` | `"3.4.18"` | Versão do plugin no momento em que a option foi gravada (não confundir com a versão instalada — confirmar sempre via `wp plugin get`) |
| `detected` | não presente hoje (array, quando existe) | Campo interno alimentado pelo endpoint REST `wpmeteor/v1/detect` (JS de admin reporta ferramentas de terceiros detectadas, ex. `"marketo"`, `"hubspot"` — dispara um aviso admin sugerindo contacto com o autor do plugin para optimizações extra) |
Estes **5 módulos são o catálogo completo e definitivo** desta versão do
plugin (`3.4.18`) — confirmado por leitura de todo o código-fonte, não só
da option gravada. **O plugin NÃO tem** (verificado directamente no
código, ausência confirmada, não assumida):
- Lazy loading de imagens/iframes — zero.
- Defer/async de scripts como toggle independente — o mecanismo de delay
é tudo-ou-nada por script, controlado só pelo `ultimate-reorder`.
- Remoção de query strings de assets estáticos.
- Preconnect/dns-prefetch configurável — existe um `preconnect: true`
interno calculado automaticamente (`frontend_adjust_wpmeteor` em
`UltimateReorder.php`), mas não há opção na UI nem chave na option para
o utilizador controlar.
- Critical CSS / CSS não usado.
- Qualquer módulo específico de WooCommerce (existe apenas uma exclusão
automática fixa para um script de troca de classe `woocommerce-no-js` →
`woocommerce-js`, dentro do módulo interno `Compatibility`, não é um
módulo à parte nem é configurável).
Não confundir com outros plugins de performance (WP Rocket, Autoptimize,
etc.) que têm estas features — o WP Meteor é deliberadamente um plugin de
um truque só (delay de JS), bem executado, com módulos de compatibilidade
à volta desse truque.
---
## Como funciona o `ultimate-reorder` (delay/facade pattern)
Padrão clássico de optimização de TBT/INP: em vez de deixar o browser
executar todo o JavaScript da página logo no carregamento (bloqueando a
main thread), o plugin **intercepta os `<script>` da página, remove-os da
execução imediata, e só os dispara quando**:
1. o utilizador interage pela primeira vez (`mousemove`, `scroll`,
`touchstart`, `click`, `keydown` — eventos típicos deste padrão), **ou**
2. o `delay` configurado expira — aqui **2 segundos fixos**.
O que ganha: a página fica "interactive-looking" mais cedo, porque o
JavaScript pesado (analytics, widgets, sliders, tracking) não compete pela
main thread durante o first paint/LCP.
O que pode perder: **qualquer script que controle dimensões, posição ou
visibilidade de elementos visíveis acima da dobra fica também atrasado** —
porque o mecanismo não distingue "JS de tracking" de "JS que a página
precisa para se renderizar correctamente". Se um elemento Elementor depende
de JS para calcular a sua altura final, ícones (`sub-arrow`, Font Awesome),
carrosséis do hero, ou animações que definem `opacity`/`transform` no
carregamento, esses elementos **saltam de posição/tamanho quando o script
finalmente corre** (aos 2s ou na primeira interacção) — a definição exacta
de Cumulative Layout Shift.
### Valores possíveis para `ultimate-reorder.delay` (confirmado no código, `UltimateReorder.php`)
A chave `delay` não é só "número de segundos" — tem 3 comportamentos
distintos consoante o valor gravado (a option guarda string, o PHP faz
`(int)` antes de usar):
| Valor gravado | Comportamento em runtime (`rdelay`, ms enviados ao JS) | Quando usar |
|---|---|---|
| `"0"` | `rdelay = 0` — scripts disparam assim que possível, sem espera fixa (chamado **"zero delay mode"** pelo próprio autor, promovido num aviso admin permanente em `Enqueue.php`) | Sites onde o TBT já é baixo e só se quer o reorder/facade, sem atraso artificial |
| `"2"`, `"5"`, etc. (positivo) | `rdelay = delay * 1000` ms — timeout fixo, script corre ao fim de N segundos **mesmo sem interacção** | Caso geral — garante que scripts de tracking correm mesmo em sessões sem interacção (bounces) |
| `"-1"` (ou qualquer negativo) | `rdelay = 86400000` (24h em ms, na prática "nunca por timeout") — **scripts só correm na primeira interacção real do utilizador**, nunca por timeout | Máxima agressividade de TBT/INP; risco: sessões sem interacção (bots de SEO/Lighthouse, utilizadores que só leem) nunca disparam analytics/pixels |
| módulo `enabled=false` | `rdelay = 0` e o rewrite de scripts não corre — comportamento idêntico a ter o plugin desligado | Teste de isolamento (ver secção de diagnóstico CLS) |
Nota de compatibilidade legada (irrelevante para `v3.4.18` mas presente no
código): em options gravadas por versões `< 2.3.6`, `delay=3` era mapeado
automaticamente para o comportamento "-1" (só interacção). Não se aplica a
options novas.
---
## Configurar exclusões (o gap real encontrado nesta sessão)
`exclude.value` é um array de strings (URL, palavra-chave ou regex) que
identificam o `src`/conteúdo inline de scripts a **não atrasar**. Hoje está
vazio — nada escapa ao atraso de 2s.
```bash
# Adicionar exclusões (substitui o array inteiro — ler primeiro, escrever depois)
sudo -u USER /usr/local/bin/wp option patch update wp-meteor-settings exclude value \
'["gtag","googletagmanager","gtm.js","analytics","elementor-pro/assets/js/frontend","font-awesome"]' \
--format=json --path=$PATH
# Alterar só o delay (ex.: reduzir de 2s para 0.5s para testar impacto)
sudo -u USER /usr/local/bin/wp option patch update wp-meteor-settings ultimate-reorder delay "0.5" --path=$PATH
# Desligar o módulo por completo (teste de isolamento — ver secção seguinte)
sudo -u USER /usr/local/bin/wp option patch update wp-meteor-settings ultimate-reorder enabled false --format=json --path=$PATH
# Confirmar
sudo -u USER /usr/local/bin/wp option get wp-meteor-settings --format=json --path=$PATH
```
**Candidatos reais a excluir** (com base na descrição da própria opção +
nesta investigação de CLS):
- Google Analytics / GTM (`gtag`, `googletagmanager`, `gtm.js`) — nunca
deve ser atrasado, quebra tracking dos primeiros 2s de cada sessão.
- Chat widgets (Tawk, Crisp, WhatsApp floating button) — se aparecem
instantaneamente no design, precisam de correr logo.
- Menus e carrosséis do hero — mencionados explicitamente na descrição da
opção como candidatos.
- Formulários acima da dobra (Elementor Pro Forms) — se o utilizador pode
interagir antes dos 2s, o JS de validação/submit tem de já estar activo.
- JS que controla ícones/dimensões de elementos visíveis no first paint
(Font Awesome, `elementor-pro/assets/js/frontend`) — candidato directo
ligado à investigação de CLS 0,89 desta sessão.
**⚠️ Não alterar em produção sem GATE de mutação** — esta é uma option viva
a servir tráfego real. Qualquer patch aqui é imediato e sem staging.
---
## Exclusões automáticas embutidas (não vêm da option, vêm do código — `GDPR.php` + `Compatibility.php`)
Além do `exclude.value` manual, há **duas camadas de exclusão automática**
que correm sempre que o módulo respectivo está `enabled=true` (ou sempre,
no caso de `Compatibility`), independentes do que está gravado na option.
Isto explica por que alguns scripts "escapam" ao atraso mesmo com
`exclude.value: []`.
### Módulo `gdpr` — regex por plugin de cookies detectado (`blocker/Exclusions/GDPR.php`)
Quando `gdpr.enabled=true` (default), o plugin testa `is_plugin_active()`
para 8 plugins de cookies conhecidos e, para cada um activo, adiciona
automaticamente os padrões correspondentes à lista de "não atrasar":
| Plugin de cookies detectado | Padrões excluídos automaticamente |
|---|---|
| Sempre (independente de plugin) | `ap.legalblink.it/api/scripts/lb_cs.js` (LegalBlink) |
| Complianz (`complianz-gdpr(-premium)`) | id `cmplz-cookiebanner` |
| Cookie Notice (`cookie-notice`) | `var cnArgs`, `/cookie-notice/js/front(.min).js` |
| GDPR Cookie Compliance / Moove (`gdpr-cookie-compliance`) | jQuery, `var moove_frontend_gdpr_scripts`, `var gdpr_consent__strict`, `/gdpr-cookie-compliance/dist/scripts/main.js` |
| Cookie Law Info / CookieYes (`cookie-law-info`) | `var _ckyConfig`, `/cookie-law-info/lite/frontend/js/script(.min).js` |
| EU Cookie Law (`eu-cookie-law-compliance`) | jQuery, `window.hasPolisClConsent` |
| Iubenda (`iubenda-cookie-law-solution`) | `var _iub`, `cdn.iubenda.com` |
| Cookiebot (`cookiebot`) | `consent.cookiebot.com/uc.js` |
| Cookie Script (`cookie-script-com`) | `cookie-script.com/s/…js` |
⚠️ Se `function_exists('is_plugin_active')` falhar (raro, contexto sem
`wp-admin/includes/plugin.php` carregado), o código assume **todos** os
plugins como activos e aplica todos os padrões de uma vez — não é um bug a
corrigir, é o comportamento de fallback do próprio plugin.
### Módulo interno `Compatibility` — sempre activo, sem toggle, sem entrada na option (`blocker/Exclusions/Compatibility.php`)
Este blocker **não aparece em nenhum separador da UI nem tem chave própria
na option** — corre sempre, com prioridade 100 (a mais baixa, ou seja,
aplicado por último). Contém uma lista fixa de ~25 padrões regex para não
atrasar scripts-chave de outros optimizadores/plugins, para evitar
conflitos duplos de optimização:
- Lazy loaders: Autoptimize (`lazyLoadOptions`), LazySizes
(`lazySizesConfig`, `lazysizes(.min).js` — com excepções para Avada/
WPSol addons), WP Rocket lazy load, Rocket Lazy Load CPCSS
(`wprRemoveCPCSS`), Easy Image Optimizer (`eio_lazy_vars`), EWWW
(`ewww_webp_supported`), Smush (`smush-lazy-load(-native).min.js`),
Jetpack Lazy Images (`jetpack-lazy-images-js-enabled`, `lazy-images.js`).
- Fast Velocity Minify (`function fvmuag(`).
- Page builders / temas: Divi (`function et_core_page_resource_fallback(`,
troca de classe `no-js`→`js`), Avada/Fusion (`fusionNavIsCollapsed`),
UpSolution (`window.\$us === undefined`).
- Swift Performance Lazyload (`data-swift-image-lazyload`).
- New Relic (`js-agent.newrelic.com`).
- WooCommerce (troca de classe `woocommerce-no-js`→`woocommerce-js`) — o
único ponto de contacto do plugin com WooCommerce, **não é um módulo
WooCommerce dedicado**.
- WPForms (`var wpforms_settings`).
- Complianz — camada extra dinâmica: lê o filtro `cmplz_known_script_tags`
e a option `complianz_options_custom-scripts` (bloqueios custom
configurados no próprio Complianz) e exclui esses URLs também, em cima
da lista fixa do módulo `gdpr` acima.
---
## Diagnóstico CLS/CWV — ligação à investigação em aberto
Contexto completo: `BUNDLE-Excelencia-WP.md` §2.2 (Performance) e
`CONFIG-Plugins-Referencia.md` §4 (WP Meteor).
Estado da investigação (`emanuelalmeida.pt`, LCP mobile 4,7s / **CLS
desktop 0,89**, não resolvido):
1. **Rocket Loader (Cloudflare, App for Cloudflare®)** — testado e
**descartado** nesta sessão: desligado, purge de cache, novo trace →
CLS manteve-se em 0,89. Não era a causa.
2. **WP Meteor `ultimate-reorder`** — **ainda não testado**, é o candidato
mais forte agora: atraso fixo de 2s, **zero exclusões configuradas**,
mecanismo bem mais agressivo que a reordenação leve do Rocket Loader.
O `<i class="fa">` (Font Awesome) encontrado no HTML durante a
investigação do CLS vem exactamente deste módulo.
Este é o próximo passo concreto documentado — **não uma conclusão**. Testar
antes de decidir se se desliga o módulo, se se reduz o `delay`, ou se se
preenche a lista de exclusões.
---
## Testar isoladamente via Chrome DevTools performance trace
Padrão usado nesta sessão para isolar a causa do CLS: baseline → mudar UMA
variável → purge de todos os caches → novo trace → comparar.
### 1. Baseline (config actual: `ultimate-reorder` ligado, `delay=2`, sem exclusões)
```
mcp__chrome_devtools_navigate_page(url: "https://emanuelalmeida.pt/")
mcp__chrome_devtools_performance_start_trace(reload: true, autoStop: true)
# aguardar conclusão do trace (autoStop com timeout suficiente para cobrir o delay de 2s)
mcp__chrome_devtools_performance_stop_trace()
mcp__chrome_devtools_performance_analyze_insight(insightName: "CLSCulprits") # ou "LayoutShifts"
```
Registar o CLS reportado e os elementos culpados (`culprits`) — normalmente
identifica o selector/elemento exacto que salta.
### 2. Alterar a variável a testar (via SSH, fora do browser)
```bash
# Opção A — desligar o módulo por completo (teste mais bruto, isola se é o WP Meteor)
sudo -u USER /usr/local/bin/wp option patch update wp-meteor-settings ultimate-reorder enabled false --format=json --path=$PATH
# Opção B — manter ligado mas excluir os scripts suspeitos (teste mais cirúrgico)
sudo -u USER /usr/local/bin/wp option patch update wp-meteor-settings exclude value '["font-awesome","elementor-pro"]' --format=json --path=$PATH
```
### 3. Purgar TODOS os caches antes de repetir o trace
O HTML/JS servido está em pelo menos duas camadas de cache — sem purgar
ambas, o browser continua a ver a versão antiga:
```bash
# WP Fastest Cache
sudo -u USER /usr/local/bin/wp cache flush --path=$PATH
# (ou, se o WPFC não expõe flush nativo por wp-cli, apagar via admin/plugin action)
# Cloudflare (App for Cloudflare® — purge via wp-admin ou API directa da zona)
```
### 4. Repetir o trace e comparar
```
mcp__chrome_devtools_navigate_page(url: "https://emanuelalmeida.pt/")
mcp__chrome_devtools_performance_start_trace(reload: true, autoStop: true)
mcp__chrome_devtools_performance_stop_trace()
mcp__chrome_devtools_performance_analyze_insight(insightName: "CLSCulprits")
```
Comparar o valor de CLS e os `culprits` antes/depois. Se o CLS cair de
forma consistente com o módulo desligado (opção A) mas os `culprits`
apontarem para os mesmos elementos com exclusões configuradas (opção B),
confirma que o `ultimate-reorder` é a causa e que a exclusão cirúrgica
resolve sem perder o ganho de TBT nos restantes scripts.
### 5. Reverter se o teste não resolver
Se o CLS não mudar com o módulo desligado, **reverter imediatamente** ao
estado original (não deixar o site sem o ganho de performance do WP Meteor
por um teste que não confirmou a hipótese):
```bash
sudo -u USER /usr/local/bin/wp option patch update wp-meteor-settings ultimate-reorder enabled true --format=json --path=$PATH
sudo -u USER /usr/local/bin/wp option get wp-meteor-settings --format=json --path=$PATH # confirmar
```
---
## Interface admin — localização e separadores (`backend/views/admin.php`)
`wp-admin` → **Definições → WP Meteor**
(`options-general.php?page=wp-meteor`, capacidade `manage_options`).
Página com 3 separadores fixos (não há mais nenhum, confirmado no template):
| Separador (UI) | Slug interno (`tab`) | Módulo(s) renderizado(s) aqui |
|---|---|---|
| Settings | `ultimate` | `ultimate-reorder` |
| Exclusions | `exclusions` | `exclude`, `gdpr` |
| Elementor | `elementor` | `elementor-animations`, `elementor-pp` |
O módulo interno `Compatibility` não tem `$tab` definido — nunca aparece
em nenhum separador, coerente com não ser configurável pelo utilizador.
---
## Mecanismos de bypass/auto-desactivação automáticos (confirmado em `frontend/Base.php` + `backend/Enqueue.php`)
O plugin desliga-se a si próprio (não faz rewrite de scripts nessa
página/pedido) nas seguintes condições, **sem qualquer intervenção manual
necessária**:
- Query string com `wpmeteordisable` em qualquer posição — desactiva o
plugin nesse pedido (útil para QA sem alterar a option: `?wpmeteordisable=1`).
- Query string com `wpmeteordebug` — mantém o plugin activo mas carrega a
variante `public-debug.js` (não minificada, com logging) em vez de
`public.js`.
- `User-Agent` a corresponder a `/fastpixel/i`.
- `Referer` igual a `https://www.squirrly.co`.
- Constante `NITROPACK_VERSION` definida — **incompatibilidade
declarada**, dispara aviso de erro admin permanente.
- Constante `FASTPIXEL_VERSION` definida — idem.
- WP Rocket activo (`WP_ROCKET_VERSION`) **e** a opção `delay_js` do WP
Rocket está ligada — o WP Meteor desliga-se para não duplicar o
mecanismo, com aviso admin a pedir para desligar um dos dois.
- Pedido não é frontend (admin, ajax, cron, REST) — via `Is_Methods::is_frontend()`.
- Filtro `wpmeteor_enabled` devolve `false` (hook para terceiros/temas
desligarem programaticamente).
- Parâmetros GET/POST de modo de edição de **19 page builders** conhecidos:
`bricks`, `brizy-edit-iframe`, `builder` (Fusion), `ct_builder`
(Oxygen), `elementor-preview`, `et_fb` (Divi), `fb-edit` (Fusion),
`fl_builder` (Beaver Builder), `preview` (Gutenberg/block editor),
`tb-preview` (Themify), `tve` (Thrive), `uxb_iframe` (Flatsome UX
Builder), `vc_action`/`vc_editable`/`vcv-action` (WPBakery), `wyp_mode`/
`wyp_page_type` (YellowPencil), `zionbuilder-preview` (Zion Builder).
- Endpoint AMP activo (`is_amp_endpoint()` ou `ampforwp_is_amp_endpoint()`).
- Modo editor/preview activo detectado directamente via classe do builder
(não só GET/POST): Elementor (`Plugin::$instance->editor`/`preview`),
Beaver Builder (`FLBuilderModel::is_builder_active()`), WPBakery
(`vc_is_inline()`), Divi (`et_core_is_builder_used_on_current_request()`),
Avada/Fusion Builder (`Fusion_App::get_instance()->is_builder`).
- Content-Type da resposta diferente de `text/html` (ex.: JSON, XML,
feeds) — nunca reescreve respostas não-HTML.
- Página `wp-login.php`.
Isto é relevante para diagnóstico: se um script continuar "não atrasado"
mesmo com o módulo `ultimate-reorder` ligado e sem exclusão manual,
confirmar primeiro se a página em causa não cai numa destas condições de
bypass antes de suspeitar de bug/exclusão em falta.
---
## Endpoint REST `wpmeteor/v1/detect` (`rest/Marketing.php`)
`POST /wp-json/wpmeteor/v1/detect` — sem autenticação declarada no
registo da rota (`register_rest_route`, sem `permission_callback`
restritivo visível). Recebe `{"data": [...]}` do JS de admin/frontend,
junta ao array `detected` já gravado na option, corta para os últimos 20
valores (`array_slice(..., -20)`) e grava de volta.
Uso conhecido: o JS reporta strings como `"marketo"` ou `"hubspot"`
quando detecta esses formulários na página; se `detected` contém um destes
valores, `backend/Enqueue.php` mostra um aviso admin permanente sugerindo
contacto com o autor do plugin (`alex@excitingstartup.com`) para
optimizações adicionais específicas dessas ferramentas — **não é uma
funcionalidade que o utilizador configure**, é telemetria/marketing do
próprio plugin.
```bash
# Ler o campo detected (se existir) directamente da option
sudo -u USER /usr/local/bin/wp option get wp-meteor-settings --format=json --path=$PATH | jq '.detected'
```
---
## Comandos WP-CLI próprios — confirmação: NÃO existem
Procurado `WP_CLI::add_command` / `\WP_CLI` em todo o código-fonte do
plugin (`grep -rl 'WP_CLI'` em todos os `.php`) — **zero resultados**. A
única referência a `WP_CLI` no plugin é em `engine/Is_Methods.php`, e é
apenas a verificação `defined('WP_CLI') && WP_CLI` para detectar se o
pedido actual corre em contexto de CLI (usado internamente para decidir
que classes carregar), **não** um comando registado. `wp help meteor` ou
qualquer variante não existe — toda a interacção via linha de comandos é
através dos comandos genéricos `wp option get`/`wp option patch` sobre
`wp-meteor-settings`, como documentado nas secções acima.
---
## Mecânica interna do rewrite de `<script>` (para debugging avançado, `UltimateReorder.php::frontend_rewrite`)
Quando `ultimate-reorder.enabled=true`, o buffer HTML de saída é
reescrito via `ob_start()` (`frontend/Rewrite.php::buffer_start`), e cada
`<script>` sofre uma destas transformações:
- Scripts inline são temporariamente substituídos por um delimitador
único (`WPMETEOR` + password aleatória de 16 chars) para não serem
reprocessados por engano por regex subsequentes que corram sobre JSON
inserido por outros scripts — só no fim são recolocados no buffer.
- `src="..."` passa a `data-wpmeteor-src="..."` (o browser não carrega o
recurso até o JS do plugin trocar o atributo de volta).
- `type="text/javascript"` (ou ausência de `type`, ou `module`) passa a
`type="javascript/blocked" data-wpmeteor-type="..."` — o browser
reconhece `type` desconhecido e não executa o script.
- `onload=`/`onerror=` em `<html|body|img|iframe>` são envolvidos para
disparar `window.dispatchEvent(new CustomEvent('fpo:element-loaded', …))`
antes do handler original, permitindo ao motor do plugin reagir a
carregamento de imagens/iframes mesmo com scripts atrasados.
- Atributo de escape manual por tag: `data-wpmeteor-nooptimize="true"`
num `<script>` específico impede que **esse** script seja atrasado,
independentemente de exclusões globais — mecanismo usado pelo próprio
plugin para o seu script de bootstrap injectado, mas também disponível
para debugging manual (adicionar o atributo directamente no HTML de um
script problemático, via filtro `the_content` ou tema, para testar sem
tocar na option).
- Scripts já marcados por outros plugins como `data-src=`,
`data-wpmeteor-type=`, `data-pmdelayedscript=` ou
`data-rocketlazyloadscript=` são ignorados (evita duplo-delay).
O filtro `wpmeteor_exclude` (booleano, `$exclude, $content` → bool) é o
ponto de extensão central — tanto o `exclude.value` manual como as
exclusões automáticas do `gdpr` e do `Compatibility` são implementadas
como listeners deste mesmo filtro, testados por ordem de prioridade até
um devolver `true`.
---
## Gotchas / erros comuns
| Sintoma | Causa | Solução |
|---|---|---|
| Trace mostra CLS igual antes/depois de mudar a config | Cache (WPFC e/ou Cloudflare) ainda a servir HTML/JS antigo | Purgar as duas camadas de cache antes de cada trace, nunca só uma |
| `wp option patch` falha com "No data exists for key" | Caminho de chaves errado — `exclude` tem sub-chave `value`, não é directamente o array | Usar `wp option patch update wp-meteor-settings exclude value '[...]'` (dois níveis) |
| `wp plugin get wp-meteor` devolve vazio noutro site do bundle | Plugin não está instalado nesse site — confirmado em `carstuff.pt` | Nunca assumir presença; confirmar por site antes de qualquer diagnóstico |
| CLS não muda mesmo com `ultimate-reorder` desligado | Causa pode estar noutro módulo (tema, Elementor, imagens sem dimensões) | Não parar na primeira hipótese testada — este é só o próximo suspeito, não a conclusão |
| Analytics/GTM param de disparar nos primeiros segundos | `exclude.value` vazio — GA/GTM ficam sujeitos ao atraso de 2s como qualquer outro script | Adicionar `gtag`/`googletagmanager`/`gtm.js` à lista de exclusões |
| Confundir `elementor-pp` com "compatibilidade Elementor Pro" | O nome sugere isso mas o título real no código é "Emulate Elementor Powerpack Pro menu" — é sobre o plugin de terceiros Elementor PowerPack Pro (Livemesh) | Verificar se o site usa mesmo PowerPack Pro antes de investir tempo a testar este módulo como causa de um problema |
| Script continua a correr "atrasado" mesmo depois de o adicionar a `exclude.value` | Já está coberto por uma exclusão automática embutida (`gdpr` ou `Compatibility`) que corre por regex diferente do valor manual, ou a página cai numa das condições de bypass automático (builder em modo preview, WP Rocket `delay_js`, etc.) | Confirmar primeiro as secções "Exclusões automáticas embutidas" e "Mecanismos de bypass" antes de assumir que a exclusão manual falhou |
| `delay` gravado como `"-1"` e analytics/pixels param de disparar em sessões sem interacção | Comportamento esperado — `-1` significa "só corre na primeira interacção real", nunca por timeout (rdelay=86400000ms) | Se o site precisa de garantia de disparo mesmo sem interacção (bounces), usar um valor positivo, nunca `-1` |
| `wp help meteor` ou comando WP-CLI próprio não existe | O plugin não regista nenhum comando WP-CLI — confirmado por grep a todo o código-fonte | Usar sempre `wp option get/patch` sobre `wp-meteor-settings`, nunca procurar um comando dedicado |
---
## Fonte
`CONFIG-Plugins-Referencia.md` §4 (WP Meteor — mapeado 16-08-2026) +
`BUNDLE-Excelencia-WP.md` §2.2 (Performance) e tabela de pendências (linhas
218 e 233) + verificação SSH ao vivo desta sessão em `emanuelalmeida.pt`
(`wp option get wp-meteor-settings --format=json`, `wp plugin get
wp-meteor --format=json`) + **leitura completa do código-fonte do plugin**
via SSH (`find wp-content/plugins/wp-meteor -iname '*.php' | xargs wc -l`
para mapear as 5718 linhas em todos os `.php`, seguido de leitura integral
de `wp-meteor.php`, `engine/{Initialize,Base,Is_Methods}.php`,
`blocker/{Base,Event}.php`, `blocker/FirstInteraction/{Base,
UltimateReorder}.php`, `blocker/Exclusions/{Exclude,GDPR,Compatibility}.php`,
`blocker/Integration/{ElementorAnimations,ElementorPP}.php`,
`backend/{SettingsPage,SaveSettings,Enqueue,ActDeact,InstUninst}.php`,
`backend/views/admin.php`, `frontend/{Base,Rewrite}.php`,
`functions/functions.php` e `rest/Marketing.php`, na sessão de expansão de
16-08-2026). Catálogo de módulos confirmado como completo e definitivo
para `v3.4.18` — não há funcionalidades por documentar além das listadas
neste ficheiro. Nenhuma alteração foi feita em produção.