Documentation

Prerendering

The <t> component and the t pipe translate in the browser. If you prerender your Angular app, you can translate your pages at build time instead. The HTML is then translated before it is sent, users never wait for a translation, and search engines index every language.

The example project prerenders one page per language. Open the German page and inspect the network traffic: no request is made to the Magic Translate API.

Translate in a resolver

Add a route parameter for the language, and translate the page's texts in a route resolver with the translate method. Store the result in Angular's TransferState, so the browser reuses it instead of translating again after hydration.

import { inject, makeStateKey, TransferState } from '@angular/core';
import { ResolveFn } from '@angular/router';
import { MagicTranslate, type Languages } from '@magic-translate/angular';
const texts = {
title: 'Welcome to our shop',
intro: 'This page was translated when the app was built.'
};
type Texts = Record<keyof typeof texts, string>;
export const translationsResolver: ResolveFn<Texts> = async (route) => {
const transferState = inject(TransferState);
const magicTranslate = inject(MagicTranslate);
const lang = (route.paramMap.get('language') ?? 'en') as Languages;
const key = makeStateKey<Texts>(`translations-${lang}`);
const transferred = transferState.get(key, null);
if (transferred) return transferred;
const entries = await Promise.all(
Object.entries(texts).map(async ([name, text]) => [
name,
await magicTranslate.translate(text, { lang })
])
);
const translations = Object.fromEntries(entries) as Texts;
transferState.set(key, translations);
return translations;
};
// app.routes.ts
export const routes: Routes = [
{
path: ':language',
component: Page,
resolve: { translations: translationsResolver }
}
];

With withComponentInputBinding() in provideRouter, the resolved translations arrive as an input of the page component.

Prerender every language

Tell Angular which languages to prerender with getPrerenderParams:

// app.routes.server.ts
import { RenderMode, ServerRoute } from '@angular/ssr';
export const serverRoutes: ServerRoute[] = [
{
path: ':language',
renderMode: RenderMode.Prerender,
getPrerenderParams: async () =>
['en', 'de', 'zh'].map((language) => ({ language }))
}
];

ng build now writes one translated HTML file per language. The translations are cached, so later builds only pay for text that changed.