Retour au blog
i18nPrismaNext.jsTypeScript

Construire un portfolio multilingue avec Prisma et Next.js

Comment j'ai modélisé un schéma trilingue (FR/EN/MG) qui scale, sans librairie i18n lourde.

Publié le 22 avril 20264 min de lecture

Pourquoi pas next-intl ?

Pour un portfolio, je ne voulais pas payer le coût d'une librairie i18n complète : routing localisé, middleware, segments dynamiques. Trois langues, du contenu statique-ish, et la plupart de la traduction stockée en base — un React.Context fait le job.

const messages: Record<Locale, Messages> = { fr, en, mg };

export function useI18n() {
  return React.useContext(I18nContext);
}

Le pattern "champ suffixé"

Plutôt qu'une table de traductions normalisée (Translation { entityId, lang, field, value }), je suffixe les colonnes :

model Project {
  descFr String
  descEn String
  descMg String
}

Avantages :

  • Une seule requête pour récupérer un projet en n'importe quelle langue
  • Pas de JOIN ni de cache busting par langue
  • TypeScript voit toutes les colonnes — pas de cast

Inconvénient : ajouter une langue = migration. À 3 langues sur un portfolio perso, c'est OK.

Le hook useLocalized()

export function useLocalized() {
  const { locale } = useI18n();
  return useCallback((row, base) => {
    const suffix = locale === "fr" ? "Fr" : locale === "en" ? "En" : "Mg";
    return row[`${base}${suffix}`] ?? row[`${base}Fr`];
  }, [locale]);
}

Dans un composant : const t = useLocalized(); t(project, "desc").

Bilan

3 langues, 0 ms de runtime i18n, 0 dépendance externe. Le SEO ? Une seule URL canonique en FR pour le moment ; je rajouterai /en et /mg quand le contenu mérite l'investissement.