Un site qui migre vers une architecture headless conserve généralement son historique d’URL, ses redirections accumulées au fil des années, souvent gérées via une extension comme Redirection ou le module correspondant de Yoast SEO. Sur une installation WordPress classique, ces extensions interceptent la requête HTTP avant même que WordPress ne la traite, et renvoient directement le code 301 ou 302 approprié. Sur un front découplé, ce mécanisme ne fonctionne plus : les requêtes n’atteignent jamais WordPress en tant que serveur web, elles passent par le serveur du front (Next.js, Nuxt, ou un CDN statique).
Il faut donc reconstituer ce comportement ailleurs, dans la couche middleware du front, en s’appuyant sur les règles toujours stockées côté WordPress. Cet article détaille comment exposer ces règles via l’API REST et les appliquer avant le rendu de page, sans entrer dans le sujet plus large du SEO headless.
Exposer les redirections via une route REST
Ni Redirection ni le module de Yoast n’exposent nativement leurs règles à l’API REST publique : il faut créer une route dédiée qui interroge leurs tables ou options internes. Pour l’extension Redirection, les règles sont stockées dans une table personnalisée (wp_redirection_items) :
add_action( 'rest_api_init', function () {
register_rest_route( 'monsite/v1', '/redirections', array(
'methods' => 'GET',
'callback' => 'monsite_get_redirections',
'permission_callback' => '__return_true',
) );
} );
function monsite_get_redirections() {
global $wpdb;
$rows = $wpdb->get_results(
"SELECT url, action_data, action_code
FROM {$wpdb->prefix}redirection_items
WHERE status = 'enabled'"
);
$redirections = array();
foreach ( $rows as $row ) {
$data = json_decode( $row->action_data, true );
$redirections[] = array(
'source' => $row->url,
'destination' => $data['url'] ?? '',
'statusCode' => (int) $row->action_code,
);
}
return rest_ensure_response( $redirections );
}
Interroger directement la table plutôt que de passer par les fonctions internes de l’extension évite une dépendance fragile à une API PHP non documentée pour un usage externe ; en contrepartie, cette requête doit être revérifiée après chaque montée de version majeure de l’extension.
Appliquer les redirections dans le middleware du front
Côté front, la liste des redirections doit être consultée avant le rendu de la page demandée, idéalement en périphérie (middleware Next.js, hook server de Nuxt) plutôt qu’au sein du composant de page lui-même, pour préserver un code de statut HTTP correct plutôt qu’une redirection JavaScript côté client.

export async function middleware(request) {
const { pathname } = request.nextUrl;
const redirections = await fetch(
'https://exemple.fr/wp-json/monsite/v1/redirections'
).then((res) => res.json());
const regle = redirections.find((r) => r.source === pathname);
if (regle) {
const url = request.nextUrl.clone();
url.pathname = regle.destination;
return Response.redirect(url, regle.statusCode);
}
}
Sur un site avec plusieurs centaines de redirections, interroger l’API à chaque requête n’est pas réaliste en termes de latence : il faut mettre cette liste en cache côté front (variable en mémoire rafraîchie périodiquement, ou fichier généré au build pour un site statique), avec une invalidation déclenchée à la modification d’une règle.
Préserver le code de statut HTTP
Le point le plus souvent négligé : une redirection appliquée via useEffect et router.push côté client renvoie un code 200 au robot d’indexation avant de rediriger visuellement l’utilisateur, ce qui ne transmet aucun signal de redirection permanente aux moteurs de recherche. Seule une redirection décidée au niveau du middleware ou du serveur peut renvoyer un véritable code 301 ou 302 dans la réponse HTTP.
| Emplacement de la redirection | Code HTTP réel renvoyé | Fiable pour le SEO |
|---|---|---|
| Middleware / edge, avant rendu | 301 ou 302 selon la règle | Oui |
| Composant de page, après hydratation | 200 (redirection JS ensuite) | Non |
Cas des redirections avec expressions régulières
Redirection permet de définir des règles basées sur des expressions régulières plutôt que sur une correspondance exacte. Le middleware doit alors tester chaque règle avec une correspondance de motif plutôt qu’une simple égalité de chaîne :
- Convertir la syntaxe stockée côté WordPress vers l’objet
RegExpdu front, en échappant les caractères spéciaux non voulus. - Tester les règles dans l’ordre de priorité défini dans Redirection, la première correspondance devant l’emporter.
- Prévoir un test automatisé sur les règles les plus critiques (anciennes URL à fort trafic historique), pour détecter une régression après une modification du middleware.
Sur une migration vers le headless, je traite toujours les redirections comme un livrable à part entière, testé avant la bascule : c’est souvent la cause principale d’une perte de trafic organique après un changement d’architecture, bien avant les questions de performance.
En résumé
Un plugin de redirections WordPress ne fonctionne plus tel quel sur un front découplé : il faut exposer ses règles via une route REST dédiée, puis les appliquer dans le middleware du front, avant le rendu de page, pour préserver un vrai code de statut HTTP. Le cache de cette liste et le test des règles à correspondance de motif sont les deux points qui demandent le plus d’attention en production.