diff --git a/packages/brisa/src/utils/get-locale-from-request/index.test.ts b/packages/brisa/src/utils/get-locale-from-request/index.test.ts index 4b2c4c6f3..e0592b03b 100644 --- a/packages/brisa/src/utils/get-locale-from-request/index.test.ts +++ b/packages/brisa/src/utils/get-locale-from-request/index.test.ts @@ -27,16 +27,6 @@ describe('utils', () => { expect(locale).toBe('ru'); }); - it('should return req.i18n.locale when exist', () => { - const request = extendRequestContext({ - originalRequest: new Request('https://example.com/ru'), - }); - request.i18n = { locale: 'en' } as any; - const locale = getLocaleFromRequest(request); - - expect(locale).toBe('en'); - }); - it('should return default locale if not locale', () => { const request = extendRequestContext({ originalRequest: new Request('https://example.com'), diff --git a/packages/brisa/src/utils/get-locale-from-request/index.ts b/packages/brisa/src/utils/get-locale-from-request/index.ts index 2b7c304f6..fddd8a478 100644 --- a/packages/brisa/src/utils/get-locale-from-request/index.ts +++ b/packages/brisa/src/utils/get-locale-from-request/index.ts @@ -2,8 +2,6 @@ import { getConstants } from '@/constants'; import type { I18nConfig, RequestContext } from '@/types'; export default function getLocaleFromRequest(request: RequestContext): string { - if (request.i18n?.locale) return request.i18n.locale; - const { I18N_CONFIG = {} as I18nConfig, LOCALES_SET } = getConstants(); const { pathname } = new URL(request.finalURL); const [, locale] = pathname.split('/'); diff --git a/packages/brisa/src/utils/handle-i18n/index.test.ts b/packages/brisa/src/utils/handle-i18n/index.test.ts index c9a1314ea..018f7d8ca 100644 --- a/packages/brisa/src/utils/handle-i18n/index.test.ts +++ b/packages/brisa/src/utils/handle-i18n/index.test.ts @@ -436,6 +436,19 @@ describe.each(BASE_PATHS)('handleI18n util %s', (basePath) => { expect(req.i18n.locale).toBe('ru'); }); + it('should not redirect to force another language different than the accept-language header', () => { + const req = extendRequestContext({ + originalRequest: new Request('http://localhost:3000/ru/foo', { + headers: { + 'Accept-Language': 'en-GB,en;q=0.9', + }, + }), + }); + req.finalURL = 'http://localhost:3000/ru/foo'; + const { response } = handleI18n(req); + expect(response).toBeUndefined(); + }); + it('should redirect to the last browser language as default locale if there is no locale in the URL', () => { const req = extendRequestContext({ originalRequest: new Request('https://example.com', { diff --git a/packages/brisa/src/utils/resolve-action/index.test.tsx b/packages/brisa/src/utils/resolve-action/index.test.tsx index 0fe36e46d..6e47f7a54 100644 --- a/packages/brisa/src/utils/resolve-action/index.test.tsx +++ b/packages/brisa/src/utils/resolve-action/index.test.tsx @@ -18,6 +18,7 @@ let mockLog: ReturnType; const getReq = (url = 'http://localhost', ...params: any) => extendRequestContext({ originalRequest: new Request(url, { + method: 'POST', headers: { 'x-action': 'some-action', }, @@ -432,7 +433,7 @@ describe('utils', () => { normalizeHTML(`
Test
- `), + `), ); }); @@ -535,6 +536,46 @@ describe('utils', () => { expect(response.headers.get('X-Mode')).toBe('reactivity'); }); + it('should be possible to navigate to another i18n locale + accept-language header', async () => { + globalThis.mockConstants = { + ...(getConstants() ?? {}), + PAGES_DIR, + BUILD_DIR, + SRC_DIR: BUILD_DIR, + ASSETS_DIR, + LOCALES_SET: new Set(['en', 'es', 'ca']), + I18N_CONFIG: { + locales: ['en', 'es', 'ca'], + defaultLocale: 'en', + }, + }; + const error = new Error('/ca'); + error.name = 'navigate:native'; + + const req = getReq('http://localhost/en'); + req.i18n = { + defaultLocale: 'en', + locales: ['en', 'es', 'ca'], + locale: 'en', + t: (v) => v, + pages: {}, + overrideMessages: () => {}, + }; + req.headers.set( + 'accept-language', + 'en,es-ES;q=0.9,es;q=0.8,de-CH;q=0.7,de;q=0.6,pt;q=0.5', + ); + const response = await resolveAction({ + req, + error, + actionId: 'a1_1', + component: () =>
, + }); + + expect(response.headers.get('X-Navigate')).toBe('/ca'); + expect(response.headers.get('X-Mode')).toBe('native'); + }); + it('should navigate with trailing slash', async () => { globalThis.mockConstants = { ...(getConstants() ?? {}), diff --git a/packages/brisa/src/utils/transfer-store-service/index.ts b/packages/brisa/src/utils/transfer-store-service/index.ts index 2271cd30d..8d09fe194 100644 --- a/packages/brisa/src/utils/transfer-store-service/index.ts +++ b/packages/brisa/src/utils/transfer-store-service/index.ts @@ -14,7 +14,11 @@ export default async function transferStoreService(req: RequestContext) { const isFormData = contentType?.includes('multipart/form-data'); const formData = isFormData && bodyAvailable ? await req.formData() : null; const encryptedKeys = new Set(); - const body = !isFormData && bodyAvailable ? await reqClone.json() : null; + const body = + !isFormData && bodyAvailable + ? await reqClone.json().catch(() => null) + : null; + const originalStoreEntries = formData ? JSON.parse(formData.get('x-s')?.toString() ?? '[]') : body?.['x-s'];