From 8feb618250e637f9154d433dc46740272c48749d Mon Sep 17 00:00:00 2001
From: ramistodev <168463169+ramistodev@users.noreply.github.com>
Date: Tue, 14 Apr 2026 10:56:02 +0200
Subject: [PATCH] refactor(i18n): dynamic locale routing with [lang] pages
- Replace hardcoded pages/es/ with dynamic pages/[lang]/
- getStaticPaths now uses locales/defaultLocale from translations.ts
- Remove hardcoded 'es' strings from AlgoViz.tsx and Header.tsx
- Add missing translation keys (openMenu, closeMenu, sidebarAriaLabel, etc.)
---
src/components/AlgoViz.tsx | 33 +++++++++---------
src/components/Header.tsx | 44 +++++++++++++++++++-----
src/i18n/translations.ts | 54 ++++++++++++++++++++++++------
src/pages/[algorithm].astro | 10 +++---
src/pages/[lang]/[algorithm].astro | 27 +++++++++++++++
src/pages/[lang]/index.astro | 20 +++++++++++
src/pages/es/[algorithm].astro | 23 -------------
src/pages/es/index.astro | 8 -----
src/pages/index.astro | 5 +--
tsconfig.json | 1 +
10 files changed, 153 insertions(+), 72 deletions(-)
create mode 100644 src/pages/[lang]/[algorithm].astro
create mode 100644 src/pages/[lang]/index.astro
delete mode 100644 src/pages/es/[algorithm].astro
delete mode 100644 src/pages/es/index.astro
diff --git a/src/components/AlgoViz.tsx b/src/components/AlgoViz.tsx
index 4f73293..ee887d5 100644
--- a/src/components/AlgoViz.tsx
+++ b/src/components/AlgoViz.tsx
@@ -5,6 +5,8 @@ import {
getAlgorithmDescription,
getAlgorithmMetaTitle,
getAlgorithmMetaDescription,
+ defaultLocale,
+ locales,
} from '@i18n/translations'
import { algorithms, categories } from '@lib/algorithms'
import { usePlayback } from '@hooks/usePlayback'
@@ -26,13 +28,16 @@ const COLLAPSE_THRESHOLD = 100
const MOBILE_BREAKPOINT = 768
function getAlgorithmUrl(locale: string, algoId: string): string {
- return locale === 'es' ? `/es/${algoId}` : `/${algoId}`
+ return locale === defaultLocale ? `/${algoId}` : `/${locale}/${algoId}`
}
function getAlgorithmIdFromPath(pathname: string): string | null {
const cleaned = pathname.replace(/\/$/, '')
- if (cleaned === '' || cleaned === '/es') return null
- if (cleaned.startsWith('/es/')) return cleaned.slice(4)
+ if (cleaned === '') return null
+ for (const locale of locales) {
+ if (cleaned === `/${locale}`) return null
+ if (cleaned.startsWith(`/${locale}/`)) return cleaned.slice(locale.length + 2)
+ }
return cleaned.slice(1)
}
@@ -249,7 +254,7 @@ export default function AlgoViz({ locale = 'en', initialAlgorithmId }: AlgoVizPr
style={{
width: sidebar.isDragging ? sidebar.width : sidebar.collapsed ? 0 : SIDEBAR_MAX,
}}
- aria-label={locale === 'es' ? 'Categorías de algoritmos' : 'Algorithm categories'}
+ aria-label={t.sidebarAriaLabel}
aria-hidden={sidebar.collapsed}
inert={sidebar.collapsed || undefined}
>
@@ -314,19 +319,19 @@ export default function AlgoViz({ locale = 'en', initialAlgorithmId }: AlgoVizPr
className={`fixed top-0 left-0 bottom-0 w-[280px] bg-black z-50 border-r border-white/8 transition-transform duration-300 ease-in-out ${
mobileSidebarOpen ? 'translate-x-0' : '-translate-x-full'
}`}
- aria-label={locale === 'es' ? 'Categorías de algoritmos' : 'Algorithm categories'}
+ aria-label={t.sidebarAriaLabel}
aria-hidden={!mobileSidebarOpen}
inert={!mobileSidebarOpen || undefined}
>
- {locale === 'es' ? 'Algoritmos' : 'Algorithms'}
+ {t.mobileMenuTitle}