How to Localize an Existing Angular App with Angular Universal With all SEO aspects - Part One
Localization is essential for any web application targeting a global audience. It involves adapting your application to different languages and regions, providing users with a seamless experience in their native language. If you already have an Angular application and are using Angular Universal for server-side rendering (SSR), localizing your app might seem challenging. However, with the right approach, you can effectively localize your existing Angular app while leveraging Angular Universal's benefits. This article will guide you through the process.
1. Install Localization Packages
Localization in Angular requires the @angular/localize
package. If your existing app doesn’t include this package, install it:
ng add @angular/localize
This package enables Angular's built-in i18n (internationalization) capabilities, which are necessary for handling translations.
1. Prepare Your Application for Localization
Extract Translatable Content: Use Angular’s i18n system to mark text in your templates that needs translation. For example, add the
i18n
attribute to your HTML elements:<h1 i18n="@@welcomeMessage">Welcome to our application!</h1>
Extract Translations: Generate an extraction file using Angular CLI:
ng extract-i18n
This command produces a
messages.xlf
file in your project’s root directory, containing all marked text strings. You can then use this file to create translations for other languages.Create Translation Files: Create a
src/locale
directory and add translation files for each supported language, such as:src/locale/messages.ar.xlf
for Arabicsrc/locale/messages.ar-SA.xlf
for Saudi Arabic
Each file should include translations for the corresponding language.
If you have several alternate URLs targeted at users with the same language but in different locales, it's a good idea to also provide a catchall URL for geographically unspecified users of that language. For example, if you have specific URLs for English speakers in Ireland (
en-ie
), Canada (en-ca
), and Australia (en-au
), provide a generic English (en
) page for searchers in the US, UK, and all other English-speaking locations. It can be one of the specific pages, if you choose. Source
3. Configure Localization in Angular
To serve localized content, you must configure the Angular build system for each language:
Update
angular.json
: Open theangular.json
file and add ani18n
section:"i18n": { "sourceLocale": { "baseHref": "/", "code": "en-US" }, "locales": { "ar-SA": { "translation": "src/locale/messages.ar-SA.xlf", "baseHref": "ar-SA/" }, "ar": { "translation": "src/locale/messages.ar.xlf", "baseHref": "ar/" } } },
Configure Build Options: Under the
projects -> architect -> build -> configurations
section, add configurations for each language:"ar-sa": { "localize": ["ar-SA"] }, "ar": { "localize": ["ar"] },
Serve Localized Content: Modify the
serve
configuration under theprojects -> architect -> serve -> configurations
section:"ar": { "browserTarget": "my-app:build:ar" }, "ar-SA": { "browserTarget": "my-app:build:ar-SA" }
5. Integrate Localization with Angular Universal
Angular Universal requires additional configuration to handle server-side rendering for localized content. Follow these steps:
Update
server.ts
to Detect Locale: Modify the server logic to detect and serve the correct locale based on the request URL.export function app(lang: string){ const server = express(); const distFolder = join(BROWSER_BASE_PATH, 'build', lang); const indexHtml = existsSync(join(distFolder, "index.original.html")) ? "index.original.html" : "index"; server.engine("html", ngExpressEngine({ bootstrap: AppServerModule, providers: [ {provide: LOCALE_ID, useValue: lang}, {provide: APP_BASE_HREF, useValue: `/${lang}`} ], })); ..... server.get("*", (req, res) => { res.render(join(distFolder, "index.html"), { req, providers: [ {provide: APP_BASE_HREF, useValue: `/${lang}`}, {provide: REQUEST, useValue: req}, {provide: RESPONSE, useValue: res}, {provide: LOCALE_ID, useValue: lang} ] }, (error, html)=>{ if (error) { res.end(indexHtml); } else { res.end(html); } }) }) } function run() { const port = process.env.PORT || 4000; const appEn = app('en-US'); const appAr = app('ar'); const appArSA = app('ar-SA'); const server = express(); server.use('/ar', appAr); server.use('/ar-SA', appArSA); server.use('/en', appEn); server.use('/en-US', appEn); .... server.listen(port, () => { console.log(`Node Express server listening on http://localhost:${port}`); }); }
Serve Localized Server Bundles: Ensure the server serves the appropriate server bundle based on the detected locale in the URL by creating a new file called
proxy-server.ts
:const express = require("express"); const path = require("path"); const getTranslatedServer = (lang) => { const distFolder = path.join( process.cwd(), `build/server/${lang}` ); const server = require(`${distFolder}/main.js`); return server.app(lang); }; function run() { const port = process.env.PORT || 4000; // Start up the Node server const appAr = getTranslatedServer("ar"); const appArSA = getTranslatedServer("ar-SA"); const appEnUS = getTranslatedServer("en-US"); const server = express(); server.get("/health_check", (req, res) => { res.status(200) .send(); }); server.use("/ar", appAr); server.use("/ar-SA", appArSA); server.use("/en-US", appEnUS); server.listen(port, () => { console.log(`Node Express server listening on http://localhost:${port}`); }); } run();
6. Build and Deploy the Localized Application
Once everything is configured, build your localized Angular application:
ng build --localize && cpx proxy-server.js dist
node ./dist/proxy-server.js
Your application should now serve the correct localized version based on the URL, providing users with content in their preferred language.
Conclusion
Localizing an existing Angular app with Angular Universal enhances your application's reach and user experience by delivering content in multiple languages. By following this guide, you can set up a robust localization system, ensuring that your application caters to a global audience. With Angular Universal, you also ensure that your localized content is delivered efficiently, improving both performance and SEO.