#middleware

1 messages · Page 1 of 1 (latest)

knotty sable
#

Salut, je voudrais écrire un middleware pour que mon utilisateur ne vois pas ma lang local dans l'url. Dans mes pages j'utilise [lang] pour le fr et le en mais je veux que le fr ne ce voit pas comme ca:
Quand un utilisateur accède à /fr/quelque-chose, le middleware doit réécrire vers /quelque-chose, car /fr/ est ta langue par défaut et tu ne veux pas qu’elle apparaisse dans l’URL.

/fr/about → /about

/fr → /

/en/about → reste /en/about (non modifié, tu pourrais le gérer si tu veux)

/robots.txt, /sitemap.xml, /styles.css, etc. → non réécrits

/pages
├── about.astro → /about (fr)
/pages/en/
├── about.astro → /en/about

candid latchBOT
#

Hi @knotty sable. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

Bonjour ! Pour répondre à ton besoin, tu veux masquer le préfixe de la langue par défaut (ici, "fr") dans l’URL, même si tes pages sont organisées avec un dossier [lang]. Tu veux donc que /fr/about soit accessible via /about, et que /en/about reste /en/about.

Astro ne fournit pas directement ce comportement via la configuration standard, mais tu peux l’implémenter avec un middleware qui réécrit les URLs commençant par /fr/ (sauf pour certains fichiers comme /robots.txt, /sitemap.xml, etc.).

Voici comment tu pourrais écrire ce middleware :

// src/middleware.js
export function onRequest(context, next) {
  const url = new URL(context.request.url);
  const pathname = url.pathname;

  // Liste des chemins à ne pas réécrire
  const exceptions = [
    "/robots.txt",
    "/sitemap.xml",
    "/favicon.ico",
    "/styles.css",
    "/manifest.webmanifest"
    // Ajoute ici d'autres fichiers statiques si besoin
  ];

  // Si le chemin est une exception, ne rien faire
  if (exceptions.includes(pathname)) {
    return next();
  }

  // Si l'URL commence par /fr/ ou est exactement /fr, on réécrit vers la version sans /fr
  if (pathname === "/fr") {
    return context.rewrite("/");
  }
  if (pathname.startsWith("/fr/")) {
    return context.rewrite(pathname.replace(/^\/fr/, ""));
  }

  // Sinon, on continue normalement
  return next();
}

Ce middleware :

  • Réécrit /fr vers /
  • Réécrit /fr/quelque-chose vers /quelque-chose
  • Laisse les autres langues (comme /en/about) inchangées
  • Ignore les fichiers statiques listés dans exceptions
#

Remarque importante : Ce type de réécriture fonctionne bien si tu utilises prefixDefaultLocale: true dans ta config i18n, et que tes pages sont bien organisées dans /pages/about.astro (pour le français) et /pages/en/about.astro (pour l’anglais). Si tu utilises la configuration i18n d’Astro, assure-toi que le routing correspond à cette logique : Voir la doc sur le routing i18n.

Pour plus d’informations sur la réécriture dans le middleware, consulte la section dédiée de la documentation : Astro Middleware - Rewriting.

N’hésite pas si tu veux affiner ce comportement ou gérer d’autres cas !

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@knotty sable Kapa.ai is still learning and improving, please let me know how I did by reacting below.

knotty sable
#

on y est presque mais c'est pas tout a fait ça, en fait je veux que mon utilisateur quand il cherche siteUrl/team on lui fournisse la page en interne de /fr/team car fr est local mais si il cherche /en/team alors on lui donne la /en/team sans la rewrite normal

#

@candid latch on y est presque mais c'est pas tout a fait ça, en fait je veux que mon utilisateur quand il cherche siteUrl/team on lui fournisse la page en interne de /fr/team car fr est local mais si il cherche /en/team alors on lui donne la /en/team sans la rewrite normal

candid latchBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

Merci pour la clarification !
Ce que tu veux, c’est :

  • Quand un utilisateur visite /team, il voit la page française (/fr/team) sans que l’URL change (donc /team reste affiché).
  • Quand il visite /en/team, il voit la page anglaise.
  • Les autres fichiers statiques ou routes spéciales ne doivent pas être réécrits.

Astro permet ce comportement avec la configuration i18n en utilisant prefixDefaultLocale: false (ce qui fait que la langue par défaut n’a pas de préfixe dans l’URL) et en plaçant les fichiers français directement dans src/pages/, tandis que les autres langues sont dans des sous-dossiers (src/pages/en/).
Aucune réécriture n’est nécessaire dans ce cas, car Astro gère déjà ce comportement nativement :

Exemple d’arborescence :

src/pages/
├── team.astro         // français, accessible via /team
└── en/
    └── team.astro     // anglais, accessible via /en/team

Extrait de configuration :

// astro.config.mjs
import { defineConfig } from "astro/config";
export default defineConfig({
  i18n: {
    locales: ["fr", "en"],
    defaultLocale: "fr",
    routing: {
      prefixDefaultLocale: false
    }
  }
});
  • /team affichera la version française.
  • /en/team affichera la version anglaise.
  • Pas besoin de middleware personnalisé pour ce comportement, c’est le fonctionnement standard d’Astro avec cette config !

Référence :
Astro i18n routing – prefixDefaultLocale: false
Configuration i18n

Résumé :

  • Place tes pages françaises à la racine de src/pages/
  • Place tes pages anglaises dans src/pages/en/
  • Utilise prefixDefaultLocale: false dans la config i18n
#

Si tu veux absolument utiliser un middleware pour d’autres raisons, précise-le, mais pour ce besoin précis, Astro gère déjà tout sans code supplémentaire.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@knotty sable Kapa.ai is still learning and improving, please let me know how I did by reacting below.

knotty sable
#

@knotty sable je trouve ça assez dingue de dupliquer la totalité de mes fichier .astro dans pages et de dire "c'est très bien gèrer"

#

@candid latch je trouve ça assez dingue de dupliquer la totalité de mes fichier .astro dans pages et de dire "c'est très bien gèrer" mais bon je crois on va faire avec

candid latchBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

Je comprends ta frustration : devoir dupliquer tous les fichiers .astro pour chaque langue peut sembler lourd, surtout pour la langue par défaut. Cependant, c’est effectivement la méthode recommandée par Astro pour gérer les routes localisées lorsque tu veux que la langue par défaut n’ait pas de préfixe dans l’URL (prefixDefaultLocale: false). Les fichiers de la langue par défaut doivent être à la racine de src/pages/, tandis que les autres langues sont dans des sous-dossiers :

src/pages/
├── about.astro         // français (par défaut) → /about
└── en/
    └── about.astro     // anglais → /en/about

Astro ne propose pas, à ce jour, de mécanisme natif pour éviter cette duplication tout en gardant une structure de routes propre et localisée sans préfixe pour la langue par défaut. C’est une limitation actuelle de la gestion i18n basée sur le file-based routing d’Astro : chaque langue correspond à un fichier ou dossier distinct, ce qui permet aussi une personnalisation complète du contenu par langue, mais implique cette duplication de structure Voir la doc.

Si tu veux éviter la duplication, il faudrait alors passer par une approche plus dynamique (par exemple, en utilisant des collections de contenu et des routes dynamiques), mais cela implique de gérer la logique de rendu et de traduction dans tes composants, ce qui peut être plus complexe Voir l’exemple de collections pour contenu traduit.

#

En résumé : oui, c’est la méthode standard avec Astro aujourd’hui, et il n’existe pas de solution native pour éviter cette duplication tout en gardant une URL sans préfixe pour la langue par défaut.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@knotty sable Kapa.ai is still learning and improving, please let me know how I did by reacting below.

knotty sable
#

@candid latch lorsque je veux récupèrer le path de mon url sans le lang je suis obliger de faire ca en étant prefixDefaultLocale: false,:
const { actual_lang } = Astro.props;

const currentPath = Astro.url.pathname;
const segments = currentPath.split("/").filter(Boolean);

const [, ...restPath] = segments;
let pathWithoutLang = "";
if (actual_lang == "fr") {
pathWithoutLang = segments.join("/");
} else {
pathWithoutLang = restPath.join("/");
}

y a pas plus simple?

candid latchBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

Astro ne fournit pas de fonction utilitaire native pour obtenir directement le chemin sans le préfixe de langue dans l’URL. La méthode que tu utilises (split sur /, puis filtrage selon la langue) est effectivement la façon la plus directe en l’absence d’un helper officiel.

Cependant, si tu utilises le module astro:i18n, tu peux t’appuyer sur la fonction getLocaleByPath() pour détecter la langue à partir du chemin, mais il n’existe pas de fonction dédiée pour retirer automatiquement le préfixe de langue du chemin. Il faut donc continuer à manipuler la chaîne de caractères comme tu le fais.

En résumé :
Non, d’après la documentation officielle, il n’existe pas de méthode plus simple ou native pour obtenir le chemin sans le préfixe de langue. Ta solution actuelle est donc appropriée dans ce contexte :

The knowledge sources do not explicitly mention a simpler or built-in way to strip the locale prefix from the path when using prefixDefaultLocale: false—manual string manipulation remains necessary.


Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: