I have Angular 17 project running on SSR. Everything is working fine. Now I want to add i18n support. Used Angular inbuild support. Installed @angular/localize version 17.3.12. For the time being only want to add /en locale first.
Updated angular.json
"i18n": {
"sourceLocale": "en",
"locales": {
}
},
...
"architect": {
"build": {
...
"options": {
"localize": ["en"],
"baseHref": "/en",
...
"server": {
...
"options": {
"localize": true,
Added messages.xlf file.
Modified package.json
"serve:ssr": "PORT 4000 node dist/billionlearners-uiapp/server/en/main.js",
Build is proper
/dist/billionlearners-uiapp/browser/en
/dist/billionlearners-uiapp/server/en
Withour SSR => My application is running properly. (http://localhost:4200)
With SSR => Application is running (http://localhost:4000) but does not show the links properly. All routerLinks are converted into "/en/en/<>".
I tried many different options but was unable to find the resolution. Looks like I am missing something.
My server.ts looks like below (I have only updated distFolder path and added /en)
import 'zone.js/node';
import { APP_BASE_HREF } from '@angular/common';
import { CommonEngine } from '@angular/ssr';
import * as express from 'express';
import { existsSync } from 'node:fs';
import { join } from 'node:path';
import AppServerModule from './src/main.server';
// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
const server = express();
const distFolder = join(
process.cwd(),
'dist/billionlearners-uiapp/browser/en'
);
const indexHtml = existsSync(join(distFolder, 'index.original.html'))
? join(distFolder, 'index.original.html')
: join(distFolder, 'index.html');
const commonEngine = new CommonEngine();
server.set('view engine', 'html');
server.set('views', distFolder);
// Example Express Rest API endpoints
// server.get('/api/**', (req, res) => { });
// Serve static files from /browser
server.get(
'*.*',
express.static(distFolder, {
maxAge: '1y',
})
);
// All regular routes use the Angular engine
server.get('*', (req, res, next) => {
const { protocol, originalUrl, baseUrl, headers } = req;
commonEngine
.render({
bootstrap: AppServerModule,
inlineCriticalCss: false,
documentFilePath: indexHtml,
url: `${protocol}://${headers.host}${originalUrl}`,
publicPath: distFolder,
providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }],
})
.then((html) => res.send(html))
.catch((err) => next(err));
});
return server;
}
function run(): void {
const port = process.env['PORT'] || 4000;
// Start up the Node server
const server = app();
server.listen(port, () => {
console.log(
`Node Express server listening on http://localhost:${port}`
);
});
}
// Webpack will replace 'require' with '__webpack_require__'
// '__non_webpack_require__' is a proxy to Node 'require'
// The below code is to ensure that the server is run only when not requiring the
bundle.
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = (mainModule && mainModule.filename) || '';
if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
run();
}
export default AppServerModule;
Thanks in advance.