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
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:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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}`;
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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',
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user