# Como corrigir o cache do WP Rocket que serve Custom Fields dinâmicos do ACF PRO desatualizados no WordPress

O cache ACF WP Rocket entrega valores antigos quando o WP Rocket guarda o HTML já renderizado da página e não regenera esse arquivo ao salvar um Custom Field dinâmico do ACF PRO; o visitante continua vendo o valor anterior até o cache expirar ou ser purgado.

## O que é cache do WP Rocket com Custom Fields do ACF PRO?

O cache ACF WP Rocket é o atrito entre dois comportamentos legítimos: o ACF PRO entrega o valor de um Custom Field em tempo de execução via get_field() ou the_field(), enquanto o WP Rocket salva o HTML final da página em um arquivo estático e serve esse arquivo direto, sem rodar o PHP de novo. Quando o campo é atualizado fora do fluxo normal de save_post (por um import, um cron, uma chamada REST, um update_field() em código ou a edição de uma Options Page), o WP Rocket não recebe o gatilho de limpeza e continua servindo o HTML congelado com o valor antigo.

Na prática isso se manifesta como um preço, um banner, um contador ou um texto vindo de um campo ACF que muda no painel mas não muda no site para o visitante. O conteúdo só atualiza quando o cache daquela URL expira pelo tempo de vida configurado ou quando alguém limpa o cache manualmente. A correção não é desligar o cache: é fazer o WP Rocket purgar a página certa no momento certo, usando os hooks do ACF para disparar as funções de limpeza documentadas do WP Rocket, e reservar a exclusão total apenas para o conteúdo que realmente muda a cada requisição.

## Como identificar

- Um Custom Field do ACF PRO atualizado no painel continua mostrando o valor antigo no front-end, e só atualiza depois de limpar o cache do WP Rocket manualmente em Configurações -> WP Rocket -> Limpar cache.
- O valor novo aparece corretamente para quem está logado como administrador (que recebe a página sem cache) mas não para o visitante anônimo.
- Campos alterados por import, cron, REST API ou update_field() em código nunca refletem no site, enquanto campos salvos pelo botão Atualizar do post às vezes refletem.
- Uma Options Page do ACF foi editada e o cabeçalho ou rodapé do site inteiro continua com o conteúdo anterior em todas as páginas.
- Após adicionar a flag rocket=0 ou abrir a URL com ?nowprocket na ponta, o valor do campo aparece atualizado, confirmando que a página servida está vindo do cache.

**Antes de começar:** Edite o functions.php ou crie o plugin de site primeiro em um ambiente de staging e mantenha um backup dos arquivos e do banco antes de aplicar em produção, pois um erro de sintaxe no PHP do hook pode derrubar o site com tela branca.

## Como prevenir

- Centralize a invalidação de cache em um único hook acf/save_post no código do tema ou plugin de site, em vez de depender da limpeza manual após cada edição.
- Separe no projeto os campos que mudam por post (purga por página) dos campos globais de Options Page (limpeza global) e do conteúdo por requisição (Never Cache URLs).
- Documente quais URLs entram em Never Cache URLs para que ninguém remova a exclusão sem entender que o campo daquela página é dinâmico por usuário.
- Sempre que um import, cron ou rotina REST gravar campos ACF, chame rocket_clean_post() para o post afetado dentro da própria rotina, fechando o ciclo de atualização.

Erros relacionados

- [Como corrigir a exclusão de páginas do cache no WP Rocket](https://full.services/wp-fixer/corrigir-exclusao-cache-wp-rocket/)
- [Como resolver cache que não limpa no WordPress](https://full.services/wp-fixer/corrigir-cache-nao-limpa-wordpress/)
- [Como corrigir a lentidão do ACF PRO com muitos Custom Fields](https://full.services/wp-fixer/corrigir-performance-muitos-fields-acf-pro/)

## Causa

- O Custom Field foi gravado por update_field() em código, por import, por cron ou pela REST API, fora do botão Atualizar do editor, então o WP Rocket nunca recebeu o gatilho de limpeza que ele só associa por padrão ao salvamento do post no admin.
- O campo editado pertence a uma ACF Options Page: o valor é global e aparece em muitas URLs, mas salvar a Options Page não invalida o cache de todas essas páginas, apenas grava o option no banco.
- O tempo de vida do cache (Cache Lifespan) do WP Rocket está alto, então a página com o valor antigo permanece servida por horas até a regeneração automática acontecer.
- O bloco ou template que imprime o campo é renderizado em PHP no servidor (the_field), e não via JavaScript no navegador, então o valor fica embutido no HTML estático que o WP Rocket congelou.
- A página exibe um campo que deveria ser sempre dinâmico (contador, saldo, estoque por usuário) e está sendo cacheada sem nenhuma regra de exclusão em Never Cache URLs, entregando o mesmo HTML para todos os visitantes.

## Como resolver

1. Confirme que a página servida vem do cache: Abra a URL afetada acrescentando o parâmetro que ignora o WP Rocket e compare com a versão normal. Se o valor do campo aparecer atualizado só na versão sem cache, o problema é de invalidação e não do ACF.

```
Abra https://seusite.com/página-afetada/?nowprocket no navegador anônimo
Compare com https://seusite.com/página-afetada/ sem o parametro
Confirme se o valor novo do campo aparece apenas na URL com ?nowprocket
```

2. Limpe o cache do WP Rocket para validar a hipótese: Faça uma limpeza manual e recarregue a página como visitante. Se o valor atualizar após a limpeza, está confirmado que falta um gatilho automático de purga quando o campo muda.

```
Painel WP -> Configurações -> WP Rocket -> aba Painel -> Limpar cache
Recarregue a página afetada em uma janela anonima e verifique o valor
```

3. Purgue a página automaticamente ao salvar o campo ACF: Adicione um hook acf/save_post que dispara rocket_clean_post() para o post editado, sempre com a guarda function_exists recomendada pela documentação do WP Rocket. Assim cada atualização de campo invalida só a página correta, sem limpar o site inteiro.

```
Edite o functions.php do tema filho ou um plugin de site
Cole o snippet do bloco de código abaixo
Salve e atualize um Custom Field para confirmar que so aquela página recebe purga
```

4. Trate as Options Pages com limpeza global: Como um campo de Options Page aparece em muitas URLs, condicione a chamada de rocket_clean_domain() ao salvamento da Options Page, limpando o site inteiro só nesse caso específico em vez de uma única página.

```
No hook acf/save_post, verifique se o post_id e 'options'
Quando for 'options', chame rocket_clean_domain() em vez de rocket_clean_post()
Reserve a limpeza total apenas para esse cenario para não derrubar o cache a cada edição comum
```

5. Exclua do cache só o conteúdo realmente por requisição: Se o campo precisa mudar a cada visita (saldo, estoque ou valor por usuário), não adianta purgar: a página não pode ser cacheada. Liste essa URL em Never Cache URLs para o WP Rocket sempre regenerar o HTML.

```
Painel WP -> Configurações -> WP Rocket -> aba Avancado
Em 'Nunca armazenar em cache (URLs)' adicione o caminho da página, um por linha
Use o caminho relativo, por exemplo /minha-conta/ ou /carrinho/
```

6. Reduza o tempo de vida do cache se a purga não couber: Quando a atualização vem de cron ou import e você não controla o gatilho, diminua o Cache Lifespan para que a página com valor antigo viva menos tempo antes da regeneração automática.

```
Painel WP -> Configurações -> WP Rocket -> aba Cache
Ajuste 'Tempo de vida do cache' para um intervalo menor (ex.: 10 horas)
Equilibre: muito baixo aumenta a regeneracao e o uso de CPU do servidor
```


## Código

```php
<?php
/**
 * Purga o cache do WP Rocket quando um campo ACF e salvo.
 * Pagina unica: rocket_clean_post(). Options Page: rocket_clean_domain().
 */
add_action( 'acf/save_post', 'full_purge_rocket_on_acf_save', 20 );
function full_purge_rocket_on_acf_save( $post_id ) {

    // Options Page: campo global, limpa o site inteiro.
    if ( 'options' === $post_id || 'option' === $post_id ) {
        if ( function_exists( 'rocket_clean_domain' ) ) {
            rocket_clean_domain();
        }
        return;
    }

    // Ignora autosave, revisoes e IDs nao numericos (ex.: user_123, term_45).
    if ( ! is_numeric( $post_id ) || wp_is_post_revision( $post_id ) ) {
        return;
    }

    // Pagina unica: purga apenas o post editado.
    if ( function_exists( 'rocket_clean_post' ) ) {
        rocket_clean_post( (int) $post_id );
    }
}

/**
 * Mesmo gatilho para campos gravados fora do admin (import, cron, REST).
 * Chame esta funcao na sua rotina logo apos o update_field().
 */
function full_purge_rocket_for_post( $post_id ) {
    if ( function_exists( 'rocket_clean_post' ) ) {
        rocket_clean_post( (int) $post_id );
    }
}
```

## Perguntas frequentes

### Por que o WP Rocket mostra o valor antigo de um campo ACF que eu já atualizei

O WP Rocket serve um arquivo HTML estático já renderizado e não roda o PHP que lê o campo a cada visita. Se a atualização do campo não disparou a limpeza do cache, o visitante recebe o HTML congelado com o valor anterior até o cache expirar ou ser purgado.

### Por que o campo aparece certo para mim como administrador mas errado para o visitante

Usuários logados costumam receber a página sem cache, então você vê o valor real lido do banco. O visitante anônimo recebe a versão cacheada, que ainda guarda o valor antigo. Por isso o problema parece intermitente até você testar deslogado.

### Como faço o WP Rocket limpar o cache automaticamente quando salvo um campo ACF

Use o hook acf/save_post do ACF para chamar rocket_clean_post() com o ID do post editado, sempre dentro de function_exists para evitar erro se o WP Rocket estiver inativo. Assim cada salvamento invalida apenas a página correspondente.

### Devo desativar o cache do WP Rocket nas páginas com campos ACF

Não como regra. Desligar o cache perde o ganho de performance. Purgue a página ao salvar o campo e reserve a exclusão em Never Cache URLs apenas para conteúdo que muda a cada requisição, como saldo ou estoque por usuário.

### Editei uma Options Page do ACF e o site inteiro continua com o conteúdo antigo

Um campo de Options Page aparece em muitas URLs, então purgar uma única página não basta. No hook acf/save_post, quando o post_id for 'options', chame rocket_clean_domain() para limpar o cache do site inteiro nesse caso específico.

### Por que campos alterados por import ou cron nunca atualizam no site

O WP Rocket associa a limpeza padrão ao salvamento do post no admin. Imports, cron, REST e update_field() em código não passam por esse fluxo, então nada é purgado. Chame rocket_clean_post() dentro da própria rotina que grava o campo.

### rocket_clean_post limpa o site inteiro ou só uma página

rocket_clean_post() limpa o cache de um único post pelo ID, sem afetar o resto do site. Para limpar tudo de uma vez, em casos como Options Pages, use rocket_clean_domain(), que purga o domínio inteiro e dispara o preload quando habilitado.

### Como testo se a página que estou vendo veio do cache do WP Rocket

Acrescente ?nowprocket no fim da URL ou abra a página em uma janela anônima. Se o valor do campo aparecer atualizado apenas sem o cache, o problema é de invalidação do WP Rocket e não do ACF lendo o banco.

**Fonte:** [WP Rocket — rocket_clean_post() / rocket_clean_domain()](https://docs.wp-rocket.me/article/92-rocket-clean-domain/)
