Fix détection langue Google pour les pages arabes : hreflang + localisation UI
- decodeURIComponent dans getAlternateUrls pour matcher les pathnames arabes percent-encoded - Localisation des aria-label et title (logo, menu mobile, dark mode toggle) via i18n.ts - Ajout section ui dans les traductions (closeMenu, changeTheme, themeAuto/Light/Dark) - Refacto logo.astro : utilise getHomePath/getLocaleFromUrl au lieu de logique dupliquée - Refacto header.astro : utilise getLocaleFromUrl au lieu de détection manuelle
This commit is contained in:
parent
6df73851e5
commit
d53039c75d
5 changed files with 27 additions and 14 deletions
|
|
@ -1,12 +1,19 @@
|
||||||
---
|
---
|
||||||
// DarkModeToggle component - cycles between auto / light / dark
|
import { getLocaleFromUrl, t } from "../utils/i18n";
|
||||||
|
|
||||||
|
const currentLang = getLocaleFromUrl(Astro.url);
|
||||||
---
|
---
|
||||||
|
|
||||||
<button
|
<button
|
||||||
id="darkModeToggle"
|
id="darkModeToggle"
|
||||||
type="button"
|
type="button"
|
||||||
class="flex items-center justify-center w-8 h-8 rounded-lg cursor-pointer text-neutral-600 dark:text-neutral-300 hover:text-neutral-900 dark:hover:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800 transition-colors"
|
class="flex items-center justify-center w-8 h-8 rounded-lg cursor-pointer text-neutral-600 dark:text-neutral-300 hover:text-neutral-900 dark:hover:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800 transition-colors"
|
||||||
aria-label="Changer le thème"
|
aria-label={t('ui', 'changeTheme', currentLang)}
|
||||||
|
data-theme-labels={JSON.stringify({
|
||||||
|
auto: t('ui', 'themeAuto', currentLang),
|
||||||
|
light: t('ui', 'themeLight', currentLang),
|
||||||
|
dark: t('ui', 'themeDark', currentLang),
|
||||||
|
})}
|
||||||
>
|
>
|
||||||
<!-- Auto icon (system preference) -->
|
<!-- Auto icon (system preference) -->
|
||||||
<svg
|
<svg
|
||||||
|
|
@ -81,8 +88,8 @@
|
||||||
|
|
||||||
function updateAriaLabel(preference: 'auto' | 'light' | 'dark') {
|
function updateAriaLabel(preference: 'auto' | 'light' | 'dark') {
|
||||||
const toggle = document.getElementById('darkModeToggle');
|
const toggle = document.getElementById('darkModeToggle');
|
||||||
const labels = { auto: 'Thème : automatique', light: 'Thème : clair', dark: 'Thème : sombre' };
|
const labels = JSON.parse(toggle?.dataset.themeLabels || '{}');
|
||||||
toggle?.setAttribute('aria-label', labels[preference]);
|
toggle?.setAttribute('aria-label', labels[preference] || preference);
|
||||||
}
|
}
|
||||||
|
|
||||||
const cycle: Record<string, 'light' | 'dark' | 'auto'> = { auto: 'light', light: 'dark', dark: 'auto' };
|
const cycle: Record<string, 'light' | 'dark' | 'auto'> = { auto: 'light', light: 'dark', dark: 'auto' };
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
---
|
---
|
||||||
import Logo from "../components/logo.astro";
|
import Logo from "../components/logo.astro";
|
||||||
|
import { getLocaleFromUrl, t } from "../utils/i18n";
|
||||||
|
|
||||||
// Détection de la langue courante par le path uniquement
|
const currentLang = getLocaleFromUrl(Astro.url);
|
||||||
const pathname = Astro.url.pathname;
|
|
||||||
const currentLang = pathname.startsWith('/en') ? 'en' : pathname.startsWith('/ar') ? 'ar' : 'fr';
|
|
||||||
|
|
||||||
// Menu localisé
|
// Menu localisé
|
||||||
const menus = {
|
const menus = {
|
||||||
|
|
@ -40,7 +39,7 @@ const currentMenus = menus[currentLang] || menus.fr;
|
||||||
<button
|
<button
|
||||||
id="mobileMenuBackground"
|
id="mobileMenuBackground"
|
||||||
type="button"
|
type="button"
|
||||||
aria-label="Fermer le menu"
|
aria-label={t('ui', 'closeMenu', currentLang)}
|
||||||
class="fixed inset-0 z-20 hidden w-screen h-screen duration-300 ease-out bg-white/90 dark:bg-neutral-950/90 appearance-none border-0 p-0 cursor-default"
|
class="fixed inset-0 z-20 hidden w-screen h-screen duration-300 ease-out bg-white/90 dark:bg-neutral-950/90 appearance-none border-0 p-0 cursor-default"
|
||||||
>
|
>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,17 @@
|
||||||
---
|
---
|
||||||
import HomeIcon from "./icons/HomeIcon.astro";
|
import HomeIcon from "./icons/HomeIcon.astro";
|
||||||
|
import { getLocaleFromUrl, getHomePath, t } from "../utils/i18n";
|
||||||
|
|
||||||
const pathname = Astro.url.pathname;
|
const currentLang = getLocaleFromUrl(Astro.url);
|
||||||
const currentLang = pathname.startsWith('/en') ? 'en' : pathname.startsWith('/ar') ? 'ar' : 'fr';
|
const homeUrl = getHomePath(currentLang);
|
||||||
const isHome = pathname === '/' || pathname === '/en' || pathname === '/en/' || pathname === '/ar' || pathname === '/ar/';
|
const isHome = (Astro.url.pathname.replace(/\/$/, '') || '/') === homeUrl;
|
||||||
const homeUrl = currentLang === 'en' ? '/en' : currentLang === 'ar' ? '/ar' : '/';
|
|
||||||
---
|
---
|
||||||
|
|
||||||
{!isHome && (
|
{!isHome && (
|
||||||
<a
|
<a
|
||||||
href={homeUrl}
|
href={homeUrl}
|
||||||
class="group relative z-30 flex items-center gap-3 text-neutral-600 dark:text-neutral-300 hover:text-black dark:hover:text-white transition-colors"
|
class="group relative z-30 flex items-center gap-3 text-neutral-600 dark:text-neutral-300 hover:text-black dark:hover:text-white transition-colors"
|
||||||
title="Accueil"
|
title={t('nav', 'home', currentLang)}
|
||||||
>
|
>
|
||||||
<HomeIcon size={20} class="group-hover:scale-110 transition-transform duration-200" />
|
<HomeIcon size={20} class="group-hover:scale-110 transition-transform duration-200" />
|
||||||
<span class="font-medium text-lg tracking-wide whitespace-nowrap">Jalil Arfaoui</span>
|
<span class="font-medium text-lg tracking-wide whitespace-nowrap">Jalil Arfaoui</span>
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,13 @@ export const translations = {
|
||||||
darkMode: { fr: 'Mode sombre', en: 'Dark mode', ar: 'الوضع الداكن' },
|
darkMode: { fr: 'Mode sombre', en: 'Dark mode', ar: 'الوضع الداكن' },
|
||||||
lightMode: { fr: 'Mode clair', en: 'Light mode', ar: 'الوضع الفاتح' },
|
lightMode: { fr: 'Mode clair', en: 'Light mode', ar: 'الوضع الفاتح' },
|
||||||
},
|
},
|
||||||
|
ui: {
|
||||||
|
closeMenu: { fr: 'Fermer le menu', en: 'Close menu', ar: 'إغلاق القائمة' },
|
||||||
|
changeTheme: { fr: 'Changer le thème', en: 'Change theme', ar: 'تغيير المظهر' },
|
||||||
|
themeAuto: { fr: 'Thème : automatique', en: 'Theme: auto', ar: 'المظهر: تلقائي' },
|
||||||
|
themeLight: { fr: 'Thème : clair', en: 'Theme: light', ar: 'المظهر: فاتح' },
|
||||||
|
themeDark: { fr: 'Thème : sombre', en: 'Theme: dark', ar: 'المظهر: داكن' },
|
||||||
|
},
|
||||||
categories: {
|
categories: {
|
||||||
pro: { fr: 'Professionnel', en: 'Professional', ar: 'مهني' },
|
pro: { fr: 'Professionnel', en: 'Professional', ar: 'مهني' },
|
||||||
comedy: { fr: 'Comédie', en: 'Comedy', ar: 'كوميديا' },
|
comedy: { fr: 'Comédie', en: 'Comedy', ar: 'كوميديا' },
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,6 @@ function matchDynamicPattern(
|
||||||
export function getAlternateUrls(
|
export function getAlternateUrls(
|
||||||
pathname: string,
|
pathname: string,
|
||||||
): Record<Locale, string> | undefined {
|
): Record<Locale, string> | undefined {
|
||||||
const normalized = pathname.replace(/\/$/, "") || "/";
|
const normalized = decodeURIComponent(pathname.replace(/\/$/, "") || "/");
|
||||||
return pathIndex.get(normalized) ?? matchDynamicPattern(normalized);
|
return pathIndex.get(normalized) ?? matchDynamicPattern(normalized);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue