From 6a22c54e9f3c42c84fad275b0e1e6d1fcc401baa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joe=20K=C3=BCng?= Date: Wed, 11 Mar 2026 17:19:26 +0100 Subject: [PATCH] feat(front-end): ssr i18n fix --- frontend/src/app/app.config.ts | 52 +++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/app.config.ts b/frontend/src/app/app.config.ts index 09271b3..d76c897 100644 --- a/frontend/src/app/app.config.ts +++ b/frontend/src/app/app.config.ts @@ -1,17 +1,25 @@ import { ApplicationConfig, + provideAppInitializer, provideZoneChangeDetection, importProvidersFrom, + inject, + REQUEST, } from '@angular/core'; import { provideRouter, withComponentInputBinding, withInMemoryScrolling, withViewTransitions, + Router, } from '@angular/router'; import { routes } from './app.routes'; import { provideHttpClient, withInterceptors } from '@angular/common/http'; -import { TranslateModule, TranslateLoader } from '@ngx-translate/core'; +import { + TranslateLoader, + TranslateModule, + TranslateService, +} from '@ngx-translate/core'; import { provideTranslateHttpLoader, TranslateHttpLoader, @@ -22,6 +30,22 @@ import { withEventReplay, } from '@angular/platform-browser'; import { serverOriginInterceptor } from './core/interceptors/server-origin.interceptor'; +import { catchError, firstValueFrom, of } from 'rxjs'; + +type SupportedLang = 'it' | 'en' | 'de' | 'fr'; +const SUPPORTED_LANGS: readonly SupportedLang[] = ['it', 'en', 'de', 'fr']; + +function resolveLangFromUrl(url: string): SupportedLang { + const firstSegment = (url || '/') + .split('?')[0] + .split('#')[0] + .split('/') + .filter(Boolean)[0] + ?.toLowerCase(); + return SUPPORTED_LANGS.includes(firstSegment as SupportedLang) + ? (firstSegment as SupportedLang) + : 'it'; +} export const appConfig: ApplicationConfig = { providers: [ @@ -50,6 +74,32 @@ export const appConfig: ApplicationConfig = { }, }), ), + provideAppInitializer(() => { + const translate = inject(TranslateService); + const router = inject(Router); + const request = inject(REQUEST, { optional: true }) as + | { url?: string } + | null; + + translate.addLangs([...SUPPORTED_LANGS]); + translate.setDefaultLang('it'); + const requestedUrl = + (typeof request?.url === 'string' && request.url) || router.url || '/'; + const lang = resolveLangFromUrl(requestedUrl); + + return firstValueFrom( + translate.use(lang).pipe( + catchError((error) => { + console.error('[i18n] Failed to preload language for SSR', { + lang, + requestedUrl, + error, + }); + return of({}); + }), + ), + ).then(() => undefined); + }), provideClientHydration(withEventReplay()), ], };