update arabic to be default
Build & Push / Pipeline Tests (push) Successful in 1m56s
Test / Type Check (all packages) (push) Successful in 56s
Build & Push / Build & Push Docker Image (push) Successful in 3m39s
Test / API Unit Tests (push) Successful in 1m12s
Test / Homepage Unit Tests (push) Successful in 52s
Test / Carplace Unit Tests (push) Successful in 43s
Test / Admin Unit Tests (push) Successful in 52s
Test / Dashboard Unit Tests (push) Successful in 45s
Test / API Integration Tests (push) Successful in 1m8s

This commit is contained in:
root
2026-08-31 19:50:27 -04:00
parent f00d2a8aea
commit cb8bf63218
23 changed files with 58 additions and 77 deletions
@@ -1,6 +1,6 @@
{
"version": "1.0",
"defaultLocale": "en",
"defaultLocale": "ar",
"locales": ["en", "fr", "ar"],
"rootDetection": true,
"routes": [
@@ -82,7 +82,7 @@
},
"hreflang": {
"values": ["en", "fr", "ar"],
"xDefaultLocale": "en",
"xDefaultLocale": "ar",
"selfCanonical": true
}
}
+1 -1
View File
@@ -11,7 +11,7 @@ export type Locale = (typeof locales)[number];
export type Direction = 'ltr' | 'rtl';
export type RouteId = 'home' | 'sign-in' | 'forgot-password' | 'reset-password' | 'privacy' | 'terms' | 'accessibility';
export const defaultLocale: Locale = 'en';
export const defaultLocale: Locale = 'ar';
export const defaultMode: ThemePreference = 'dark';
export const localeCookie = 'hpc-locale';
export const localeStorageKey = 'hpc.locale';
+12 -9
View File
@@ -5,7 +5,6 @@ import {
isLocale,
localeCookie,
localeCookieMaxAgeSeconds,
localeFromAcceptLanguage,
localizedModePath,
routeIdFromAnyLocaleSlug,
routeIdFromSlug,
@@ -47,11 +46,8 @@ function resolveApiOrigin(): string | undefined {
return origins.size > 0 ? Array.from(origins).join(' ') : undefined;
}
function resolveRequestLocale(request: NextRequest) {
const cookieLocale = request.cookies.get(localeCookie)?.value;
return isLocale(cookieLocale)
? cookieLocale
: localeFromAcceptLanguage(request.headers.get('accept-language')) || defaultLocale;
function resolveRequestLocale() {
return defaultLocale;
}
function resolveRequestMode(request: NextRequest) {
@@ -69,6 +65,13 @@ function setLocaleCookie(response: NextResponse, locale: string): void {
secure: process.env.NODE_ENV === 'production',
httpOnly: false,
});
response.cookies.set(dashboardLanguageCookie, locale, {
path: '/',
sameSite: 'lax',
maxAge: localeCookieMaxAgeSeconds,
secure: process.env.NODE_ENV === 'production',
httpOnly: false,
});
}
function setModeCookie(response: NextResponse, mode: string): void {
@@ -98,7 +101,7 @@ export function proxy(request: NextRequest): NextResponse {
requestHeaders.set('Content-Security-Policy', csp);
if (request.nextUrl.pathname === '/') {
const locale = resolveRequestLocale(request);
const locale = resolveRequestLocale();
const mode = resolveRequestMode(request);
const destination = request.nextUrl.clone();
destination.pathname = `/${locale}/${mode}`;
@@ -110,11 +113,11 @@ export function proxy(request: NextRequest): NextResponse {
const pathSegments = request.nextUrl.pathname.split('/').filter(Boolean);
// Redirect locale-less paths (e.g. /sign-in -> /en/dark/sign-in), but not proxied app paths or files.
// Redirect locale-less paths (e.g. /sign-in -> /ar/dark/sign-in), but not proxied app paths or files.
const firstSegment = request.nextUrl.pathname.split('/')[1];
const isFile = /\.\w+$/.test(request.nextUrl.pathname);
if (firstSegment && !isFile && !isLocale(firstSegment) && !reservedProxySegments.has(firstSegment)) {
const locale = resolveRequestLocale(request);
const locale = resolveRequestLocale();
const mode = resolveRequestMode(request);
const destination = request.nextUrl.clone();
destination.pathname = `/${locale}/${mode}${request.nextUrl.pathname}`;
+1 -1
View File
@@ -35,7 +35,7 @@ for (const scenario of [
});
}
test('root locale detection honors Accept-Language', async ({ browser }) => {
test('root locale defaults to Arabic', async ({ browser }) => {
const context = await browser.newContext({
extraHTTPHeaders: { 'Accept-Language': 'ar;q=1,en;q=0.8' },
});
@@ -16,7 +16,7 @@ describe('localization foundations', () => {
it('selects a supported locale by quality', () => {
expect(localeFromAcceptLanguage('de-DE;q=0.9, ar;q=0.8, fr;q=0.7')).toBe('ar');
expect(localeFromAcceptLanguage('fr-CA, en;q=0.8')).toBe('fr');
expect(localeFromAcceptLanguage(null)).toBe('en');
expect(localeFromAcceptLanguage(null)).toBe('ar');
});
it('validates locale direction and route lookup', () => {
@@ -45,7 +45,7 @@ describe('localization foundations', () => {
const links = hreflangMap(new URL('https://approved.test'), 'home');
expect(links.en).toBe('https://approved.test/en/dark');
expect(links.ar).toBe('https://approved.test/ar/dark');
expect(links['x-default']).toBe('https://approved.test/en/dark');
expect(links['x-default']).toBe('https://approved.test/ar/dark');
});
it('preserves only approved campaign query values and valid hashes', () => {
+1 -1
View File
@@ -76,7 +76,7 @@ describe('homepage proxy app boundaries', () => {
expect(response).toMatchObject({
kind: 'redirect',
url: 'https://rentaldrivego.ma/fr/dark',
url: 'https://rentaldrivego.ma/ar/dark',
});
});