We are excited to announce the release of Analog 2.5! This release introduces first-class runtime i18n support, a new fast compilation mode, hierarchical content with recursive prerendering, and a new AI integrations guide. Let's dive in.
Runtime i18n 🌍
Analog 2.5 adds first-class runtime internationalization built on Angular's $localize. With a single build, your app can serve every supported locale, with the active locale detected on both the server and the client.
Setup
Install @angular/localize and import the polyfill in your application entry:
// src/main.ts
import '@angular/localize/init';
Configure the supported locales on the analog() plugin in vite.config.ts. This enables locale detection on SSR and exposes the values as build-time globals so the application config doesn't have to repeat them:
// vite.config.ts
import { defineConfig } from 'vite';
import analog from '@analogjs/platform';
export default defineConfig(() => ({
plugins: [
analog({
i18n: {
defaultLocale: 'en',
locales: ['en', 'fr', 'de'],
},
}),
],
}));
Then provide the runtime translation loader via provideI18n():
// src/app/app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideFileRouter } from '@analogjs/router';
import { provideI18n } from '@analogjs/router/i18n';
export const appConfig: ApplicationConfig = {
providers: [
provideFileRouter(),
provideI18n({
loader: async (locale) => {
const translations = await import(`../i18n/${locale}.json`);
return translations.default;
},
}),
],
};
Mark templates with the standard Angular i18n attribute:
<h1 i18n="@@greeting">Hello</h1>
On SSR, the locale is detected from the URL path prefix (/fr/about) or the Accept-Language header. On the client, it's read from window.location.pathname. The loader function you provide is called once at startup with the active locale, and $localize handles the rest.
Message Extraction
The i18n plugin option also accepts an extract config that scans the compiled output for $localize tagged templates and writes a translation source file at the end of a production build:
analog({
i18n: {
defaultLocale: 'en',
locales: ['en', 'fr', 'de'],
extract: {
format: 'json',
outFile: 'src/i18n/messages.json',
},
},
})
format supports json, xliff, xliff2, and xmb.
Switching Locales
A small helper makes runtime locale switching a one-liner:
import { Component } from '@angular/core';
import { injectSwitchLocale } from '@analogjs/router/i18n';
@Component({ /* ... */ })
export class LanguagePickerComponent {
switchLocale = injectSwitchLocale();
}
Calling switchLocale('fr') navigates to the equivalent /fr URL and re-evaluates templates with the new translations. Check out the i18n docs for the full guide.
Fast Compilation Mode ⚡️
Analog 2.5 introduces fastCompile, a new option on the analog() Vite plugin that enables a Vite-native Angular compilation pipeline combined with OXC for fast parsing. The most noticeable differences are with cold starts and HMR.
Enable it in your Vite config:
// vite.config.ts
import { defineConfig } from 'vite';
import analog from '@analogjs/platform';
export default defineConfig(() => ({
plugins: [
analog({
fastCompile: true,
}),
],
}));
A companion fastCompileMode option controls the compilation output:
-
'full'(default): Emits final Ivy definitions for application builds. -
'partial': Emits partial declarations for library publishing.
analog({
fastCompile: true,
fastCompileMode: 'partial',
})
Fast compilation mode allows you to offload type checking as a separate process, keeping the development workflow streamlined, especially when building content-focused sites and applications.
Hierarchical Content 📚
Support for hierarchical content and nested content directories has been improved for more complex documentation structure:
src/content/docs/
getting-started/
welcome.md
first-upload.md
assets/
upload.md
Content resolvers in Analog previously only handled top level folders and slugs in the src/content directory, but is now more flexible to handle nested subdirectories with existing APIs.
Slash-containing slugs
A catch-all route now resolves nested files correctly:
// src/app/pages/docs/[...slug].page.ts
import { Component } from '@angular/core';
import { injectContent, MarkdownComponent } from '@analogjs/content';
@Component({
standalone: true,
imports: [MarkdownComponent],
template: `
@if (post(); as post) {
<analog-markdown [content]="post.content" />
}
`,
})
export default class DocsPageComponent {
post = injectContent({ subdirectory: 'docs' });
}
Recursive prerendering
A new recursive option was added, and each content file now exposes a relativePath so transforms can identify identically-named files across subdirectories:
// vite.config.ts
analog({
prerender: {
routes: async () => [
{
contentDir: 'src/content/docs',
recursive: true,
transform: (file) => {
const segment = file.relativePath
? `${file.relativePath}/`
: '';
return `/docs/${segment}${file.name}`;
},
},
],
},
})
For backward compatibility, recursive defaults to false.
AI Integrations Guide 🤖
Analog 2.5 ships with a new AI integrations guide that walks through wiring LLM providers into Analog's API routes — streaming responses, server-side keys, and the usual use cases. If you're adding AI features to an app, that guide is the starting point.
We are also looking into adding official skills for Analog features and conventions.
Upgrading
To upgrade to Analog 2.5, run:
ng update @analogjs/platform@latest
If you're using Nx, run:
nx migrate @analogjs/platform@latest
For the full list of changes, see the changelog.
Partner with Analog 🤝
Continued development of Analog would not be possible without our partners and community. Thanks to our official deployment partner Zerops, code review partner CodeRabbit, and longtime supporters Snyder Technologies, Nx, and House of Angular, and many other backers of the project.
Find out more information on our partnership opportunities or reach out directly to partnerships[at]analogjs.org.
Join the Community 🥇
- Visit and Star the GitHub Repo
- Join the Discord
- Follow us on Twitter
If you enjoyed this post, click the ❤️ so other people will see it. Follow AnalogJS and Brandon Roberts on Bluesky, and subscribe to my YouTube Channel for more content!
Top comments (0)