
🔄 WordPress numa subpasta: como mover a instalação da raiz e vice-versa
Uma situação familiar: configura um site de desenvolvimento, constrói o tema, liga o conteúdo através do WP Migrate DB Pro e, depois de publicar, descobre estilos quebrados, imagens em falta e um wp-admin não funcional. A razão é quase sempre a mesma: a produção está na raiz enquanto o desenvolvimento está num subdiretório (ou vice-versa), e uma simples pesquisa e substituição de URLs na base de dados não resolve esta diferença.
O problema é mais profundo do que parece: numa instalação na raiz, o WordPress utiliza o mesmo domínio para todos os links (tanto para páginas como para ficheiros multimédia). Numa instalação em subdiretório, os links de conteúdo vêm do endereço do site, enquanto os links de recursos (css, js, imagens) vêm do endereço do WordPress. Uma pesquisa e substituição padrão na base de dados substitui tudo de forma uniforme e parte metade dos caminhos.
Neste guia, encontrará duas rotas de migração comprovadas (ida e volta) com definições específicas de pesquisa e substituição, preparação do wp-config.php e a sequência correta de transferência de ficheiros. Depois de ler, ou colocará o desenvolvimento e a produção num esquema unificado ou fará conscientemente uma migração entre diferentes tipos de instalação sem partir o frontend.
💡 Visão geral rápida:
- Determine o seu tipo de instalação: veja se "Endereço do WordPress" e "Endereço do site" coincidem em Definições → Geral
- Para migrar de subdiretório para raiz: codifique o WP_SITEURL no wp-config, faça uma substituição de
/subdir→/na base de dados, mova os ficheiros um nível acima, atualize o index.php da raiz - Para migrar da raiz para subdiretório: substitua apenas os caminhos para
/wp-contentna base de dados, atualize o endereço do WordPress nas definições, crie o subdiretório, copie o index.php e o .htaccess de volta para a raiz - Após qualquer migração, vá a Definições → Permalinks e clique em "Guardar": isto reconstrói a estrutura de URLs e limpa a cache
Como determinar onde o WordPress está instalado
Se instalou o WordPress manualmente, provavelmente lembra-se se foi na raiz do domínio ou num subdiretório como /wp ou /blog. Mas se o site foi herdado de um programador anterior, implementado pelo fornecedor de alojamento com um clique, ou já passaram vários anos, os detalhes desvanecem-se.
A forma mais rápida: vá ao painel de administração do WordPress, abra Definições → Geral e veja os campos "Endereço do WordPress (URL)" e "Endereço do site (URL)". Se os valores coincidirem, tem uma instalação na raiz:

Se os campos forem diferentes, o WordPress está instalado num subdiretório (no exemplo abaixo, é /subdir):

Um sinal adicional de uma instalação em subdiretório: ao iniciar sessão no painel de administração, o URL contém um subdiretório, por exemplo, example.com/wp/wp-admin/ em vez de example.com/wp-admin/.
Porque não pode simplesmente transferir diretamente
A raiz do problema está no sistema de URL duplo que o WordPress utiliza com instalações em subdiretório. Vamos analisá-lo com exemplos específicos.
Suponha que tem uma instalação na raiz em example.com. Absolutamente todos os links na base de dados, tanto para um artigo /2025/about-page como para uma imagem /wp-content/uploads/photo.jpg, começam com //example.com. Uma pesquisa e substituição padrão //example.local → //example.com funciona perfeitamente.
Agora considere uma instalação no subdiretório /wp. O link para o mesmo artigo é //example.com/about-page (através do endereço do site), enquanto o link para a mesma imagem é //example.com/wp/wp-content/uploads/photo.jpg (através do endereço do WordPress com o subdiretório). Uma simples substituição //example.local → //example.com vai quebrar os ficheiros multimédia: o sistema irá procurá-los sem o /wp no caminho e obterá um 404.
A tabela abaixo mostra que grupos de URLs precisam de ser atualizados em cada direção de migração:
Direção | URLs de páginas e artigos | URLs de multimédia e recursos | Caminhos de ficheiros na base de dados |
|---|---|---|---|
Subdiretório → raiz | Substituir | Substituir | Substituir |
Raiz → subdiretório | Manter como está | Substituir | Substituir |
Além da base de dados, é necessário mover fisicamente os ficheiros e atualizar o index.php na raiz, caso contrário o WordPress não encontrará o wp-blog-header.php. De seguida, vamos percorrer ambos os cenários passo a passo.
Método 1: mover o WordPress do subdiretório para a raiz
Esta é a direção mais simples: remove-se o subdiretório dos caminhos e todos os URLs ficam «planos», como numa instalação padrão.
Passo 0: diagnosticar o que vai correr mal
Antes de intervir, ajuda ver a dimensão do problema com os seus próprios olhos. A captura de ecrã abaixo mostra as definições de migração de wp-in-a-subdirectory.local (WordPress em /subdir) para wp-standard-install.local (instalação na raiz). As definições do WP Migrate DB Pro são as padrão, mais uma substituição do título do site para demonstração:

O resultado é previsivelmente desolador: as páginas abrem mas sem estilos e com imagens partidas:

No HTML, vemos links de recursos com um caminho /subdir morto que já não existe no servidor de destino. Tentar aceder ao wp-admin provoca um redirecionamento para wp-standard-install.local/subdir/wp-login.php, mas esse ficheiro não existe. Vamos agora corrigir isto.
Passo 1: preparação
Primeiro, proteja o acesso ao admin durante a migração. Adicione constantes ao wp-config.php que irão sobrepor as definições da base de dados, para que o WordPress continue a permitir-lhe entrar no admin pelo caminho antigo com o subdiretório, mesmo depois de limparmos a base de dados:
1 define( 'WP_SITEURL', 'http://wp-in-a-subdirectory.local/subdir' ); 2 define( 'WP_HOME', 'http://wp-in-a-subdirectory.local' );
Depois coloque o site em modo de manutenção: edite o index.php na raiz pública, comente a linha require( dirname( __FILE__ )... e após a tag de fecho ?> insira um placeholder html com uma mensagem breve de indisponibilidade. Os visitantes verão isto:

Entretanto, continua a aceder ao admin em http://wp-in-a-subdirectory.local/subdir/wp-admin/ porque a constante WP_SITEURL funciona.
Passo 2: pesquisar e substituir na base de dados
Agora limpe a base de dados. Execute uma pesquisa-substituição com estes pares (mostrados na interface do WP Migrate DB Pro, mas o mesmo princípio funciona com search-replace do WP-CLI ou consultas SQL via phpMyAdmin):
//wp-in-a-subdirectory.local/subdir→//wp-in-a-subdirectory.local/app/public/subdir→/app/public(caminho do ficheiro no servidor)

Imediatamente após a migração, o aspeto não muda (a página de manutenção continua ativa, o admin funciona através da constante definida no código). Mas se observar o conteúdo dos artigos, as imagens ainda não carregam e as ligações internas «perderam» o subdiretório, que é exatamente o que pretendíamos nesta fase:

Passo 3: transferência física dos ficheiros
Remova (ou comente) as linhas com WP_SITEURL e WP_HOME do wp-config.php. O admin vai deixar de funcionar, por isso mova imediatamente os ficheiros do subdiretório para o nível acima.
Via SSH ou linha de comandos no servidor, isto faz-se com três comandos:
1 rm index.php && mv subdir/* . && rm -rf subdir
Via FTP ou gestor de ficheiros do alojamento, arraste todo o conteúdo do subdiretório para a raiz pública, substituindo o index.php:

Pronto. O site abre no URL raiz; as imagens e os estilos estão no lugar:

Toque final: aceda ao admin (agora em http://wp-in-a-subdirectory.local/wp-admin sem o subdiretório), abra Settings → Permalinks e clique em «Save Changes», mesmo que não tenha alterado nada. O WordPress irá reconstruir a estrutura de URLs e limpar a cache.
Método 2: mover o WordPress da raiz para um subdiretório
Muitos programadores consideram instalar o WordPress num subdiretório uma boa prática: os ficheiros principais não sobrecarregam a raiz, a gestão via Git/Composer é simplificada e o próprio domínio pode ser usado para outras aplicações. Mas migrar um site existente para um subdiretório é objetivamente mais complexo do que o inverso, porque agora alguns links DEVEM manter o subdiretório e outros não.
Passo 0: diagnóstico
Mesmo ponto de partida: tentamos uma migração padrão da instalação na raiz wp-standard-install.local para a instalação em subdiretório wp-in-a-subdirectory.local (WordPress em /subdir):

O resultado é completamente esperado: as páginas abrem, mas os estilos e imagens quebram porque /subdir não foi adicionado aos caminhos:

Ao contrário do primeiro cenário, os links para artigos e páginas funcionam corretamente (não devem conter o subdiretório). O que quebra são especificamente os recursos (css, js, media), cujos caminhos devem agora incluir /subdir.
Passo 1: preparação
Nesta fase, NÃO definimos as constantes WP_SITEURL e WP_HOME, porque a nossa pesquisa e substituição não vai mexer nestes valores, e vamos atualizar o endereço do WordPress manualmente um pouco mais tarde.
Configure a página de manutenção da mesma forma: comente require(...) no index.php e adicione um placeholder html. Os visitantes veem a mensagem de manutenção enquanto continua a aceder ao admin em http://wp-standard-install.local/wp-admin/.
Passo 2: pesquisa e substituição seletiva na base de dados
A principal diferença em relação ao primeiro método: substituímos APENAS os caminhos de ficheiros e recursos, SEM mexer nos URLs das páginas. Para isso, direcione a substituição usando o padrão /wp-content:
//wp-standard-install.local/wp-content→//wp-standard-install.local/subdir/wp-content/app/public→/app/public/subdir(caminho no servidor)

Após a migração, verifique o conteúdo dos artigos: os links para outras páginas do site NÃO contêm o subdiretório (correto), enquanto as imagens incorporadas contêm-no (também correto):

Passo 3: atualizar o endereço do WordPress e mover os ficheiros
Agora vá a Definições → Geral e acrescente o subdiretório no final de "Endereço do WordPress (URL)", por exemplo, http://wp-standard-install.local/subdir. Imediatamente após guardar, o admin vai quebrar porque o WordPress tentará encontrar os ficheiros no novo caminho, mas eles ainda não estão lá:

Crie o subdiretório subdir na raiz pública e mova TODOS os ficheiros do WordPress para lá. Depois copie o index.php e o .htaccess DE VOLTA para a raiz, para que a página de manutenção continue a ser exibida enquanto terminamos:

Restaure o index.php DENTRO do subdiretório para o seu estado original: remova o placeholder html e descomente a linha do require:
1 <?php 2 define( 'WP_USE_THEMES', true ); 3 require( dirname( __FILE__ ) . '/wp-blog-header.php' );
Agora o admin está novamente acessível em http://wp-standard-install.local/subdir/wp-admin/:

Verifique o conteúdo: as imagens estão no lugar, os estilos estão a carregar:

Toque final: index.php na raiz
Resta apenas atualizar o index.php na raiz pública. Remova a página de manutenção e especifique o caminho correto para o wp-blog-header.php, tendo em conta o subdiretório:
1 <?php 2 define( 'WP_USE_THEMES', true ); 3 require( dirname( __FILE__ ) . '/subdir/wp-blog-header.php' );
O site abre no URL raiz com todos os recursos carregados a partir do subdiretório:

Mais uma vez, vá a Definições → Links permanentes e guarde sem alterações para que o WordPress atualize a estrutura de URLs.
Ferramentas alternativas e o método oficial
A abordagem descrita acima com o WP Migrate DB Pro é conveniente, mas não é a única opção. Eis outras ferramentas com que pode trabalhar:
*WP-CLI
search-replace.* O comandowp search-replace '//oldsite.local/subdir' '//newsite.com'com a flag--dry-runmostrará primeiro quantas ocorrências serão substituídas. Para substituição seletiva (raiz → subdiretório), restrinja o padrão:wp search-replace '//newsite.com/wp-content' '//newsite.com/subdir/wp-content'.Método oficial do WordPress. A documentação em developer.wordpress.org descreve o procedimento «Giving WordPress Its Own Directory», com configurações detalhadas para Apache (.htaccess), nginx (bloco de servidor) e IIS (web.config). O método não requer plugins e funciona em qualquer alojamento.
SQL manual. Se o volume de edições for pequeno, pode executar
UPDATE wp_posts SET post_content = REPLACE(post_content, '/subdir/', '/')diretamente no phpMyAdmin, mas sempre com uma cópia de segurança prévia, pois essa substituição destruirá dados serializados no wp_options e wp_postmeta.
Qualquer que seja a ferramenta escolhida, a regra é a mesma: ao migrar RAIZ → SUBDIRETÓRIO, substitua apenas /wp-content e caminhos de ficheiros; ao migrar SUBDIRETÓRIO → RAIZ, substitua tudo o que faça referência ao subdiretório.
⁉️🤔 Perguntas frequentes
O WP Migrate DB Pro é obrigatório para este tipo de migração?
Não. O WP Migrate DB Pro oferece simplesmente uma interface conveniente para search-replace com compreensão de dados serializados do PHP. Tecnicamente, pode realizar as mesmas substituições via WP-CLI (o comando
wp search-replacetambém trata corretamente strings serializadas) ou usar o método oficial do WordPress com transferência manual de ficheiros e edição do index.php. O plugin poupa tempo em projetos de média e grande dimensão com muitas ocorrências.
O que devo fazer se algumas imagens continuarem a não carregar após a migração?
A causa mais comum: URLs hardcoded com caminhos absolutos do servidor antigo permanecem na base de dados e não corresponderam ao padrão de substituição. Verifique o conteúdo dos posts via phpMyAdmin:
SELECT ID, post_content FROM wp_posts WHERE post_content LIKE '%/subdir/%'(ou o domínio antigo). O segundo candidato é a cache do navegador e da CDN: limpe ambas e verifique em modo anónimo.
Preciso de atualizar o.htaccess após a transferência?
Se usar links permanentes personalizados, sim, mas o WordPress fá-lo automaticamente quando clica em «Guardar» na página Definições → Links permanentes. Se o servidor não tiver permissões de escrita, o WordPress mostrará o conteúdo do.htaccess pronto para copiar manualmente. Ao migrar para um subdiretório, certifique-se de que o.htaccess da raiz (não o que está dentro do subdiretório) não contém regras que entrem em conflito com a nova estrutura.
É possível realizar a migração com zero tempo de inatividade?
Tecnicamente sim, se usar o método com redirecionamentos no.htaccess (Método I da documentação oficial do WordPress, «Without changing URLs»). Com esta abordagem, os ficheiros são movidos para o subdiretório enquanto o.htaccess da raiz direciona todos os pedidos de forma transparente para a nova localização. Os visitantes não notam a mudança. A desvantagem: permanece no mesmo domínio e o URL do site formalmente não muda (o subdiretório não é visível na barra de endereço).
Por que razão o WP Migrate DB Pro não suporta migração entre diferentes tipos de instalação de raiz?
Os programadores da Delicious Brains discutiram isto no GitHub durante quase três anos. A raiz do problema: o plugin aplica UM par search-replace a TODA a base de dados, mas a migração entre raiz e subdiretório requer substituições DIFERENTES para grupos de URLs distintos (páginas vs recursos). Determinar automaticamente que URL pertence a que grupo exigiria analisar a estrutura do conteúdo, o que vai além de um simples search-replace. Por isso, a recomendação atual é: coloque os sites num esquema de instalação unificado ANTES da migração.

Resumo: raiz ou subdiretório?
A escolha entre uma instalação do WordPress na raiz ou num subdiretório resume-se, essencialmente, a um compromisso. A instalação na raiz é mais simples: menos peças móveis, compatibilidade direta entre desenvolvimento e produção, sem surpresas com URLs duplos. A instalação em subdiretório é arquitetonicamente mais limpa: os ficheiros principais ficam isolados, apenas o index.php permanece na raiz, a atualização do WordPress via Git/Composer é mais fácil e alojar várias aplicações no mesmo domínio é mais seguro.
Se tem um site de produção e um site de desenvolvimento, coloque ambos num esquema unificado (qualquer um deles) e esqueça o problema. Se trabalha numa equipa onde alguns projetos estão historicamente na raiz enquanto outros estão em subdiretórios, agora conhece os padrões exatos de pesquisa e substituição para cada direção.
A regra principal que vale a pena guardar: ao migrar de RAIZ → SUBDIRETÓRIO, mexa apenas em /wp-content e nos caminhos dos ficheiros; ao migrar de SUBDIRETÓRIO → RAIZ, substitua tudo o que contenha o subdiretório. E clique sempre, sempre em «Guardar» nos Links permanentes após a migração.



