Cache multilíngue do WP Rocket: por que o cache das versões traduzidas some ao salvar um rascunho e a solução

Aviso de afiliados v3.1
Aviso de afiliados v3.2 (somente celular)
Ambiente de teste Família RHELAlmaLinux 9.8Nginx 1.28 + Apache 2.4WP Rocket 3.23.5.1TranslatePress 3.3.8Conferido em 17/10/2026

O cache multilíngue do WP Rocket é um cache de página guardado separadamente numa pasta de idioma para cada URL traduzida do TranslatePress. Num servidor WordPress com Nginx + Apache, rastreamos no código do WP Rocket por que o cache das páginas traduzidas sumia junto com a pasta inteira do idioma toda vez que um rascunho era salvo, e resolvemos com um código que deixa posts não publicados fora da limpeza do cache das páginas traduzidas e avisa de novo o preload sobre as URLs que nós mesmos apagamos.

O tempo até o primeiro byte, medido dentro do mesmo servidor, foi de 0,015 segundo com o cache da página traduzida e 2,492 segundos sem ele. Quando uma pasta de idioma fica vazia, os visitantes das páginas traduzidas recebem essa resposta lenta até alguém abrir a URL de novo e o cache ser recriado.

1️⃣ Como o cache multilíngue do WP Rocket se organiza: pastas por idioma e limpeza das páginas traduzidas

Uma página traduzida mostra o post original traduzido, então é fácil achar que o cache dela fica junto com o original, mas o WP Rocket faz cache das URLs traduzidas como páginas separadas. Sob a pasta de cache, pastas de idioma como [en] e [ja] aparecem ao lado das pastas dos posts originais, e os posts traduzidos ficam dentro delas com os slugs traduzidos.

wp-content/cache/wp-rocket/example.com/
sample-post/post original
index-https.html
index-mobile-https.html
en/Pasta do idioma inglês
index-https.htmlPágina inicial do inglês
sample-post-en/Post traduzido em inglês (slug traduzido)
index-https.html
index-mobile-https.html
ja/Pasta do idioma japonês
index-https.html
sample-post-ja/

Ao editar um post, a integração do WP Rocket com o TranslatePress também apaga o cache das páginas traduzidas desse post. A documentação oficial também diz que uma edição comum limpa todas as versões traduzidas, enquanto uma edição feita no editor de tradução do TranslatePress limpa só o idioma que mudou.

// wp-rocket/inc/ThirdParty/Plugins/I18n/TranslatePress.php (3.23.5.1)
'post_updated' => 'clear_post_languages',            // roda toda vez que um post é salvo

public function clear_post_languages( $post_id ) {
    // …
    $default_permalink = get_permalink( $post_id );   // o status do post não é verificado

    foreach ( $trp_settings['translation-languages'] as $language ) {
        if ( $language === $trp_settings['default-language'] ) {
            continue;
        }
        $clear_urls[] = $converter->get_url_for_language( $language, $default_permalink, '' );
    }
    // …
    rocket_clean_files( $clear_urls );
}

A função de integração converte a URL do post na URL traduzida de cada idioma e depois as passa para a função de limpeza de cache [rocket_clean_files]. Nada nesse processo verifica o status do post, então as URLs traduzidas são montadas e apagadas da mesma forma, seja o post publicado ou rascunho.

2️⃣ Salvar um rascunho: a pasta inteira do idioma é apagada

Salvar um rascunho tem a ver com o cache das páginas traduzidas. Antes de o post ser publicado, o link permanente não é um slug, e sim a forma [?p=ID do post], e o TranslatePress converte essa URL numa com caminho de idioma, como [/en/?p=ID do post].

Salvar um rascunhoSalvar no editor · wp_update_post no servidor · só mudar o título
post_updated
clear_post_languages( 123 )Integração do WP Rocket com o TranslatePress
get_permalink()→ https://example.com/?p=123 · ainda não publicado, então sem slug
get_url_for_language()→ https://example.com/en/?p=123 (igual para ja·es·de)
rocket_clean_files()
Query ?p=123 removida→ caminho /en/
Local do cache→ wp-content/cache/wp-rocket/example.com/en/
É uma pasta, então é apagada recursivamente→ O cache inteiro das páginas traduzidas em inglês é apagado

O [rocket_clean_files] tira a query da URL e encontra o local do cache só pelo caminho. Se o caminho que sobra é [/en/], isso significa a pasta inteira de cache daquele idioma, e se o alvo é uma pasta, ela é apagada recursivamente, com subpastas.

// wp-rocket/inc/functions/files.php (3.23.5.1) — dentro de rocket_clean_files()
$parsed_url = get_rocket_parse_url( $url );               // separa o caminho e a query
// …
$entry = $dir . $parsed_url['path'];                      // …/example.com/en/
// …
if ( $filesystem->is_dir( $entry ) ) {
    rocket_rrmdir( $entry, [], $filesystem );             // apaga a pasta inteira recursivamente
} else {
    $filesystem->delete( $entry );
}

A página inicial passa pelo mesmo caminho. A URL [/] é convertida em [/en/], então até salvar a página inicial publicada apaga a pasta inteira do idioma. Só mudar o título de um rascunho e salvar de novo esvaziou as pastas de cache dos quatro idiomas, e pelos horários de salvamento e registros de exclusão de cache confirmamos a mesma exclusão repetida mais de 30 vezes numa noite em que os salvamentos de rascunho se acumularam.

🧭 Salvar posts e limpar o cache das páginas traduzidas
WP RocketDiagrama explicativo
📝 Post salvo
📝 Link permanente
[get_permalink]
/sample-post/Post publicado · URL com slug
/?p=123Ainda não publicado · revisões de salvamento automático também
/Página inicial
post_updated→
🌐 URL traduzida
Caminho de idioma do TranslatePress
/en/sample-post-en/
/en/?p=123
/en/
igual para ja·es·de
✅ Caminho /en/sample-post-en/ · a pasta desse post
❌ ?p=123 removido · só sobra o caminho /en/
❌ Caminho /en/ · pasta do idioma
rocket_clean_files→
🗑️ Cache que é apagado
① Só a pasta das páginas traduzidas desse posten/sample-post-en/A página inicial do idioma e as páginas traduzidas de outros posts ficam
② A pasta inteira do idiomaen/Página inicial do idioma · também páginas traduzidas de outros posts · 20 → 0 arquivos
O link permanente de um post publicado é um slug, então a URL traduzida também aponta para esse post, e só a pasta de cache das páginas traduzidas dele é apagada.
O link permanente de um rascunho tem a forma [?p=123], então a URL traduzida vira [/en/?p=123]. Quando o [rocket_clean_files] tira a query, sobra só [/en/] e a pasta inteira do inglês é apagada; as revisões de salvamento automático do editor usam a mesma URL.
A URL [/] da página inicial é convertida em [/en/], então até salvar a página inicial publicada apaga a pasta inteira do idioma.

No código, o salvamento automático do editor segue o mesmo caminho. As revisões salvas enquanto você edita um post publicado também usam uma URL da forma [?p=].

Num site de teste com Nginx + Apache, editamos um post publicado no editor contando os arquivos das pastas de idioma. Depois do primeiro salvamento automático, as pastas de inglês e japonês ainda tinham 20 arquivos cada, e depois do segundo, um minuto mais tarde, as duas estavam em 0.

O primeiro salvamento automático cria uma revisão nova, e a partir do segundo a mesma revisão é atualizada e salva, então o [post_updated] é disparado. Se você continuar editando depois do primeiro, o cache das páginas traduzidas é apagado junto com a pasta do idioma, mesmo sem apertar o botão de salvar.

O mesmo sintoma está aberto no repositório oficial do WP Rocket como issue #6130 desde 31 de agosto de 2023. O pull request #7616 para corrigi-lo foi enviado em setembro de 2025, mas não foi incorporado, e o changelog da 3.23.5.1, lançada em 2 de outubro de 2026, também não traz correção.

3️⃣ A correção: limpar o cache das páginas traduzidas só para posts publicados

Até sair uma correção oficial, você desconecta a função de integração e a troca por uma que limpa as páginas traduzidas só quando a URL é certa. A solução alternativa publicada nos comentários da issue vai na mesma direção, saindo logo da função de integração quando o post não está publicado.

Mas uma condição que só verifica o status do post deixa dois casos. A página inicial limpa a pasta inteira do idioma ao ser salva, mesmo publicada, e quando você volta um post publicado para rascunho, o cache das páginas traduzidas não é apagado, então o post despublicado continua abrindo nas URLs traduzidas.

<?php
/**
 * Plugin Name: Rocket TranslatePress Draft Fix
 * Description: Limita a exclusão do cache das páginas traduzidas pela integração WP Rocket–TranslatePress aos casos em que a URL é certa
 */

// 1. Desconecta a função de integração do WP Rocket do post_updated e a guarda
add_action( 'init', function () {
    global $wp_filter;
    if ( empty( $wp_filter['post_updated'] ) ) {
        return;
    }
    foreach ( $wp_filter['post_updated']->callbacks as $priority => $callbacks ) {
        foreach ( $callbacks as $cb ) {
            $fn = $cb['function'];
            if ( is_array( $fn ) && is_object( $fn[0] )
                && 0 === strpos( get_class( $fn[0] ), 'WP_Rocket\\' )
                && false !== stripos( get_class( $fn[0] ), 'TranslatePress' ) ) {
                remove_action( 'post_updated', $fn, $priority );
                $GLOBALS['rtdf_original'] = $fn;
            }
        }
    }
}, 9999 );

// 2. Função substituta
add_action( 'post_updated', function ( $post_id, $after, $before ) {
    if ( empty( $GLOBALS['rtdf_original'] ) || ! class_exists( 'TRP_Translate_Press' ) ) {
        return;
    }
    $trp       = TRP_Translate_Press::get_trp_instance();
    $converter = $trp->get_component( 'url_converter' );
    $settings  = $trp->get_component( 'settings' )->get_settings();
    $languages = array_diff( $settings['translation-languages'], [ $settings['default-language'] ] );

    // Página inicial — só os arquivos de cache da página inicial do idioma, não a pasta
    if ( 'page' === get_option( 'show_on_front' ) && (int) get_option( 'page_on_front' ) === (int) $post_id ) {
        $urls = [];
        add_filter( 'trp_add_language_to_home_url_check_for_admin', '__return_false' );
        foreach ( $languages as $lang ) {
            $home = $converter->get_url_for_language( $lang, home_url( '/' ), '' );
            $dir  = WP_ROCKET_CACHE_PATH . wp_parse_url( $home, PHP_URL_HOST ) . wp_parse_url( $home, PHP_URL_PATH );
            array_map( 'unlink', glob( $dir . 'index*.html*' ) ?: [] );
            $urls[] = $home;
        }
        remove_filter( 'trp_add_language_to_home_url_check_for_admin', '__return_false' );
        do_action( 'rocket_after_clean_terms', $urls );   // avisar o preload (5️⃣)
        return;
    }

    // Salvar um post publicado — a função original do WP Rocket como está
    if ( 'publish' === $after->post_status ) {
        call_user_func( $GLOBALS['rtdf_original'], $post_id );
        return;
    }

    // Publicado → rascunho·privado·lixeira — só as páginas traduzidas da URL de antes de despublicar
    if ( 'publish' === $before->post_status ) {
        $old  = get_permalink( $before );
        $urls = [];
        add_filter( 'trp_add_language_to_home_url_check_for_admin', '__return_false' );
        foreach ( $languages as $lang ) {
            $urls[] = $converter->get_url_for_language( $lang, $old, '' );
        }
        remove_filter( 'trp_add_language_to_home_url_check_for_admin', '__return_false' );
        rocket_clean_files( $urls );
    }

    // O resto (rascunhos·revisões·salvamento automático) não tem URL traduzida, então nada é apagado
}, 10, 3 );

A primeira parte encontra a função de integração registrada pelo WP Rocket, desconecta-a do [post_updated] e guarda a função original. A função substituta limpa só os arquivos de cache da página inicial do idioma quando é a página inicial, roda a função original guardada como está para posts publicados e, quando um post publicado é retirado, encontra e apaga as páginas traduzidas usando a URL de antes.

Salvo como arquivo PHP na pasta [wp-content/mu-plugins/], ele vale na hora sem ativação, e apagar o arquivo devolve o WP Rocket ao comportamento original. Num teste com código de mesmo comportamento, salvar de novo um rascunho manteve o número de arquivos das pastas de idioma, e salvar de novo um post publicado limpou só as pastas do original e das páginas traduzidas desse post.

Antes e depois de adicionar o código acima, comparamos o número de arquivos das pastas de idioma em quatro casos no mesmo ambiente. As pastas de inglês e japonês tinham cada uma 20 arquivos de cache para PC e celular da página inicial do idioma e de quatro posts.

Antes do código, salvar um rascunho, salvar a página inicial e despublicar levaram as duas pastas a 0, e só salvar um post publicado apagou apenas o cache das páginas traduzidas desse post.

Depois do código, os 20 arquivos ficaram ao salvar um rascunho e no salvamento automático do editor. Salvar a página inicial apagou os 4 arquivos de cache da página inicial do idioma, e salvar ou despublicar um post publicado apagou só as 4 páginas traduzidas desse post, sobrando 16; a URL traduzida em inglês do post despublicado retornou 404.

CasoAntes da correçãoDepois de adicionar o códigoCache apagado depois da correção
Salvar um rascunho20 → 020 → 20Nenhum
Salvar um post publicadoSó as páginas traduzidas desse post apagadas20 → 164 páginas traduzidas desse post
Salvar a página inicial20 → 020 → 164 arquivos de cache da página inicial do idioma
Despublicar20 → 020 → 164 páginas traduzidas desse post · URL traduzida retorna 404

4️⃣ Recriação do preload perdida: status concluído preso na fila

Mesmo com os salvamentos de rascunho bloqueados, o preload não repõe arquivos de cache apagados sem o sinal de exclusão de uma função do WP Rocket. O preload do WP Rocket usa uma tabela de fila que registra um status por URL: URLs aguardando requisição ficam pendentes, as requisitadas ficam em andamento, as que têm cache viram concluídas, e as que não terminam em 3 minutos viram falhas.

Uma URL concluída volta a pendente em três casos: quando o arquivo foi removido ao fim da vida útil do cache, quando o WP Rocket enviou um sinal de exclusão ao limpá-lo, ou quando falhou há mais de 12 horas. Se você passar false como terceiro argumento do [rocket_clean_files] ou apagar os arquivos diretamente, esse sinal não é enviado, então só os arquivos de cache somem enquanto a fila ainda os mostra como concluídos.

O código que recebe o sinal de exclusão e segue limpando outros caches passa false no terceiro argumento para evitar chamadas repetidas. Quando conferimos os caches das páginas traduzidas, 3 das 65 páginas em inglês e 7 das 65 em japonês ainda estavam como concluídas na fila sem os arquivos de cache.

Um colaborador do suporte do WP Rocket também reconheceu nos comentários da issue #6130 que, depois de limpar o cache, as URLs na tabela continuam como concluídas e o estado fica dessincronizado. Uma proposta de reconciliar periodicamente a tabela com os arquivos de cache (#2939) foi fechada em 2020 sem ser implementada.

5️⃣ Registrar de novo no preload: avisar a fila sobre as URLs que você mesmo limpou

Para URLs que você mesmo apaga, uma linha que avisa o preload logo depois de apagar resolve. Quando o preload recebe o sinal [rocket_after_clean_terms], ele volta as URLs recebidas para pendentes e adiciona as que faltam na tabela.

// Depois de apagar sem o sinal de exclusão — registra de novo o array de URLs apagadas na fila do preload
rocket_clean_files( $urls, null, false );          // terceiro argumento false = sem sinal de exclusão
do_action( 'rocket_after_clean_terms', $urls );     // o preload volta essas URLs para espera (pending)

Dentro do WP Rocket, só a função de fila do preload e a integração de hospedagem SpinUpWP recebem esse sinal, e a função do preload só atualiza linhas da fila, sem apagar arquivos de cache do WP Rocket nem reenviar o sinal, então não há chamadas repetidas. Sites que limpam o cache só por funções do WP Rocket e deixam o terceiro argumento no padrão já enviam o sinal e não precisam dessa linha.

Depois de adicionar essa linha, limpamos o cache de um post com páginas traduzidas em quatro idiomas, e em 2 segundos as quatro linhas da fila passaram para pendente. Em dois testes num servidor que roda cron a cada minuto, os 8 arquivos de cache de PC e celular das páginas traduzidas foram recriados após 101 e 153 segundos. Você confere pelo status da tabela da fila e pelos arquivos da pasta de cache.

# Status dessa URL na tabela da fila (o wp_ antes do nome da tabela é o prefixo do site)
wp db query <<'SQL'
SELECT url, status, modified FROM wp_wpr_rocket_cache WHERE url LIKE '%/en/sample-post-en'
SQL
url	status	modified
https://example.com/en/sample-post-en	pending	2026-10-17 09:10:48
# Se os arquivos de cache voltaram cerca de um minuto depois
ls -l wp-content/cache/wp-rocket/example.com/en/sample-post-en/
total 240
-rw-r--r-- 1 example nobody 95084 Oct 17 18:12 index-https.html
-rw-r--r-- 1 example nobody 22352 Oct 17 18:12 index-https.html_gzip
-rw-r--r-- 1 example nobody 95083 Oct 17 18:12 index-mobile-https.html
-rw-r--r-- 1 example nobody 22348 Oct 17 18:12 index-mobile-https.html_gzip

Logo depois de apagar, o status muda para [pending], e quando o preload envia a requisição e o arquivo de cache é criado, passa a [completed]. Se o status é [completed] mas não há arquivo de cache, essa URL foi apagada sem o sinal.

Quando salvamos a página inicial e o código acima apagou os arquivos de cache da página inicial dos idiomas e enviou o sinal, as URLs da home em inglês e japonês voltaram para a fila. Os caches de PC e celular das páginas iniciais dos idiomas foram recriados no máximo na segunda execução do cron.

Em dois testes, levou 47 e 91 segundos do salvamento até o último arquivo de cache.

🔢 FAQ & conteúdo recomendado

Este post se baseia na integração do WP Rocket com o TranslatePress; as integrações com WPML e Polylang não foram verificadas. Um caso em que, com outro plugin de cache e Polylang, uma URL que ficou só com a query foi convertida na pasta de cache de nível superior e apagada inteira foi publicado no fórum de suporte do WordPress.org em julho de 2026, e também foi resolvido com um código que desconecta e envolve o callback em questão.

É a issue #9028, aberta no repositório do WP Rocket em 16 de outubro de 2026. Quando o preload registra um cache, usa a URL do slug original em vez da do slug traduzido, então as linhas das URLs traduzidas nunca recebem o status concluído nem a hora do último acesso, e são apagadas junto na limpeza semanal que remove linhas sem acesso há um mês. O prazo pode ser estendido com o filtro [rocket_preload_delay_delete_non_accessed], e o exemplo da documentação oficial usa um ano; o rascunho de correção #9029 ainda não tinha sido incorporado em 17 de outubro de 2026.

Você pode removê-lo quando a correção da issue #6130 aparecer no changelog e a função de integração passar a verificar o status do post ou URLs com query. Se o nome da função ou o hook em que ela se registra mudar, o código de desconexão não encontra o alvo e o comportamento original continua; por isso, depois de uma atualização, salve um rascunho e confira se as pastas de idioma ficaram intactas.

🧭 Posts relacionados ao WP Rocket 16 artigos · 3 ferramentas
📋 Guia de configuração do WP Rocket 📄 WP Rocket MCP Server 📄 WP Rocket e URLs em coreano 📄 nginx njs 📄 Cache multilíngue do WP Rocket 📄 Cache e gclid
📄 Teste de velocidade do WP Rocket 📝 Plugins de cache e otimização 📝 Caso de melhoria de velocidade
📋 Cache: definição e todos os campos 📄 Cache do site & cache interno do servidor
📋 TOP 7 melhores hospedagens 📄 Hospedagem rápida 2026
🛠️ Detector de WordPress 🛠️ Consulta WHOIS de domínio 🛠️ Qual é o meu IP
O que é o WP Rocket: cinco afirmações de um post que recomenda o FlyingPress comparadas com telas oficiais e medições no servidor
WordPress · WP Rocket
O que é o WP Rocket: principais recursos, desvantagens e vantagens de um plugin de cache completo
Um resumo de como o WP Rocket entrega as páginas a partir de arquivos de cache e de quanto custa.
Ver post →Conteúdo atual
Guia de configuração do WP Rocket: configurações básicas por menu e cupom de 20%
WordPress · WP Rocket
Guia de configuração do WP Rocket: configurações básicas por menu e cupom de 20%
Post que reúne as configurações básicas de cada menu do WP Rocket e os preços.
Ver post →Conteúdo atual
WP Rocket MCP Server: como lidar com o cache e as configurações usando ferramentas de IA
WordPress · MCP
WP Rocket MCP Server: como lidar com o cache e as configurações usando ferramentas de IA
Como lidar com o cache e as configurações do WP Rocket a partir de ferramentas de IA.
Ver post →Conteúdo atual
Diagrama do fluxo de requisições de URL em coreano com WP Rocket
WordPress · WP Rocket
WP Rocket e URLs em coreano
Por que o nginx não encontra o arquivo de cache por causa de maiúsculas e minúsculas na codificação de requisições de URL em coreano, e como corrigir com njs.
Ver post →Conteúdo atual
Diagrama das variáveis do nginx njs e dos caminhos dos arquivos de cache
Server · nginx
nginx njs: instalar o módulo, configurar js_set e aplicar com reload para criar variáveis JavaScript
Como instalar o módulo njs, que cria variáveis com funções JavaScript dentro da configuração do nginx, e aplicar as variáveis js_set com um reload.
Ver post →Conteúdo atual
Diagrama do fluxo de salvamento de posts com o cache multilíngue do WP Rocket
WordPress · WP Rocket
Cache multilíngue do WP Rocket
Por que salvar um rascunho apaga o cache das versões traduzidas junto com a pasta inteira do idioma, e o código que evita isso.
Ver post →Conteúdo atual
Fluxo em que uma requisição com consulta de anúncio vai ao servidor de origem quando o CDN não tem cópia, passa do nginx ao Apache e o WP Rocket remove a consulta e responde com o mesmo arquivo de cache
Server · Cache
Cache e gclid: consulta do clique no anúncio, chave de cache da página e primeiro byte medido
Mede pelo primeiro byte como a consulta gclid adicionada ao fim das URLs de clique em anúncios é ignorada e a resposta vem do arquivo de cache da URL sem consulta.
Ver post →Conteúdo atual

ℹ️ Aviso de afiliados
O conteúdo deste site contém links de afiliados. Quando um visitante compra um produto ou serviço por meio de um desses links, o site recebe uma comissão do vendedor. O valor que o comprador paga (em promoções, ele diminui ↓) não aumenta por causa disso. Preços, descontos e informações de estoque valem para o momento em que o texto foi escrito e podem ter mudado, por isso confirme com o vendedor antes de comprar. Os produtos são escolhidos e avaliados por critérios próprios, e o recebimento de comissão não influencia a ordem de apresentação nem o conteúdo das avaliações.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Demonstre sua humanidade: 5   +   2   =