
# Redirections d'URL

Restructurer un site retire des URL. Sans redirection, la seule réponse possible sur un chemin retiré est un 404, et chaque lien indexé, favori et backlink qui pointe vers lui se casse.

Le tableau `redirects` déclare ces chemins retirés et l'endroit où chacun vit désormais :

```yaml
redirects:
  - from: /products/platform
    to: /
  - from: /products/partner
    to: /partner
  - from: /login
    to: /_admin/login
    status: 302
```

## Propriétés d'une règle

| Propriété | Description                                                                                                                      |
| --------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `from`    | Chemin relatif à la racine à rediriger. Doit commencer par `/` et ne contenir ni espace, ni `?`, ni `#`.                         |
| `to`      | Où envoyer le visiteur — un chemin relatif à la racine, ou une URL absolue `http(s)://` pour passer la main à une autre origine. |
| `status`  | `301` (par défaut), `302`, `307` ou `308`.                                                                                       |

Les chaînes de requête ne font pas partie de la clé de correspondance. Une chaîne de requête entrante est préservée et reportée sur la cible ; il est donc inutile d'en encoder une dans `from`. Si `to` porte déjà sa propre chaîne de requête, l'entrante y est ajoutée avec `&`.

### Choisir un statut

| Statut | Signification                                              | À utiliser quand                                                      |
| ------ | ---------------------------------------------------------- | --------------------------------------------------------------------- |
| `301`  | Moved Permanently — transfère la popularité des liens      | L'URL est retirée définitivement. C'est le défaut et la norme.        |
| `302`  | Found — temporaire, peut réécrire la méthode de la requête | Le déplacement est temporaire et la méthode n'a pas d'importance.     |
| `307`  | Temporary Redirect — temporaire, préserve la méthode       | Un déplacement temporaire qui doit conserver un `POST` en `POST`.     |
| `308`  | Permanent Redirect — permanent, préserve la méthode        | Un déplacement permanent qui doit conserver la méthode de la requête. |

## Gestion des langues

Un `from` est mis en correspondance de la même façon que les chemins de pages sont écrits. Une règle nue correspond au chemin brut _et_ à chacune de ses variantes préfixées par une langue, et un `to` de type chemin hérite de la langue de la requête — une seule règle sert donc toutes les locales, et un visiteur français atterrit sur le remplacement français, jamais sur l'anglais :

```yaml
redirects:
  - from: /pricing
    to: /plans
```

Cette unique règle répond à `/pricing`, `/en/pricing` et `/fr/pricing`, en envoyant chacun respectivement vers `/plans`, `/en/plans` et `/fr/plans`.

Pour ne cibler qu'une seule locale, écrivez le segment de langue dans `from`. Une règle dont le chemin commence déjà par un code de langue configuré est mise en correspondance littéralement :

```yaml
redirects:
  - from: /fr/tarifs
    to: /fr/plans
```

Un `to` absolu est utilisé tel quel, sans aucune gestion de langue, puisqu'il quitte entièrement l'application.

## Priorité

Les redirections sont évaluées **après les ressources statiques** et **avant les pages** :

1. Un fichier réel du répertoire public — une règle de redirection ne peut jamais détourner une ressource servie.
2. Les règles de redirection.
3. La résolution des pages.
4. Le fourre-tout 404.

Une règle l'emporte donc toujours sur une page. Cela vaut dans les deux sens : un `from` qui correspond à un chemin que vous servez encore rend cette page inaccessible.

:::callout
**Les redirections se résolvent en exactement un saut.** Une requête qui correspond émet une seule redirection, et la cible n'est jamais remise en correspondance avec la table — `Location` vaut donc toujours littéralement ce que vous avez écrit. Les chaînes ne sont pas réduites : si `/a` doit aboutir à `/c`, écrivez `/a → /c`, pas `/a → /b → /c`.
:::

## Validation

Trois règles portant sur la table entière sont appliquées au décodage de la configuration, de sorte qu'une table cassée fait échouer `sovrium validate` au lieu de partir en production :

- **Aucun `from` en double** — chaque chemin ne peut déclarer qu'une seule règle.
- **Aucune auto-redirection** — une règle qui pointe vers son propre `from` boucle indéfiniment.
- **Aucun cycle** — `/a → /b` associé à `/b → /a` est rejeté. Le serveur ne résout jamais qu'un seul saut, mais le _navigateur_, lui, suit chaque nouvelle règle à son tour et ne se stabilise jamais.

Les cibles relatives au protocole (`//example.com`) sont également rejetées. Un navigateur les résout comme des URL absolues vers une autre origine, ce qui ferait de la table de redirections une primitive de redirection ouverte ; un passage de main vers une autre origine doit expliciter `https://` afin que l'intention soit visible en relecture.

:::callout
**La collision avec une route dynamique n'est pas détectée pour vous.** La validation ne compare `from` qu'aux chemins de pages **statiques**. Si votre application sert une route dynamique telle que `/blog/:slug`, une règle pour `/blog/my-post` masquera silencieusement cet article — aucune erreur au démarrage, aucun échec de validation. Confrontez les slugs retirés au contenu qui existe encore.
:::

## Pages connexes

- [Métadonnées de l'application](/fr/docs/app-metadata) — les autres propriétés racines d'identité.
- [Présentation des pages](/fr/docs/pages-overview) — la résolution de pages devant laquelle s'exécutent les redirections.
- [Langues](/fr/docs/languages) — les codes de langue configurés qui pilotent la correspondance par préfixe.
- [SEO et métadonnées](/fr/docs/seo-meta) — les URL canoniques, avec lesquelles un 301 doit s'accorder.
