admin管理员组文章数量:1291735
Following the step by step of this question Angular 17: SSR with i18n alongside
The solved issue from angular 17 is breaking in angular 19
Angular 19, is building different server.mjs and now if I update the proxy-server.mjs as follow
import serverEn from './server/en/server.mjs';
import serverFr from './server/fr/server.mjs';
const express = require('express');
function getPreferredLanguage(req) {
const acceptedLanguages = req.acceptsLanguages(['fr', 'en']);
return acceptedLanguages || 'fr'; // Default to 'fr' if no match is found
}
function run() {
const port = process.env.PORT || 4000;
const server = express();
// Redirect root requests to the preferred language
server.get('/', (req, res) => {
const lang = getPreferredLanguage(req);
res.redirect(`/${lang}`);
});
// Serve the language-specific servers
server.use('/fr', serverFr());
server.use('/en', serverEn());
// Handle unmatched routes
server.use((req, res) => {
res.status(404).send('Page not found');
});
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
run();
the new build server.mjs file break : TypeError: Cannot read properties of undefined (reading 'method')
Do we have a standard way to integrate i18n with Angular 19 ?
Following the step by step of this question Angular 17: SSR with i18n alongside
The solved issue from angular 17 is breaking in angular 19
Angular 19, is building different server.mjs and now if I update the proxy-server.mjs as follow
import serverEn from './server/en/server.mjs';
import serverFr from './server/fr/server.mjs';
const express = require('express');
function getPreferredLanguage(req) {
const acceptedLanguages = req.acceptsLanguages(['fr', 'en']);
return acceptedLanguages || 'fr'; // Default to 'fr' if no match is found
}
function run() {
const port = process.env.PORT || 4000;
const server = express();
// Redirect root requests to the preferred language
server.get('/', (req, res) => {
const lang = getPreferredLanguage(req);
res.redirect(`/${lang}`);
});
// Serve the language-specific servers
server.use('/fr', serverFr());
server.use('/en', serverEn());
// Handle unmatched routes
server.use((req, res) => {
res.status(404).send('Page not found');
});
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
run();
the new build server.mjs file break : TypeError: Cannot read properties of undefined (reading 'method')
Do we have a standard way to integrate i18n with Angular 19 ?
Share Improve this question asked Feb 13 at 12:44 mbagiellambagiella 3623 silver badges17 bronze badges3 Answers
Reset to default 1Error: The original error was due to attempting to call serverFr() as a function, whereas serverFr and serverEn are instances of Express applications (or objects), not functions.
Solution: The solution is to use the Express application instances (serverFr and serverEn) directly as middleware in my main server.
My corrected proxy-server.mjs, however I think we could do something more dynamic with the new generated file angular-app-engine-manifest.mjs, but there is no doc about it. If someone knows I'm interested :)
import serverEn from './server/en/server.mjs';
import serverFr from './server/fr/server.mjs';
const express = require('express');
function getPreferredLanguage(req) {
const acceptedLanguages = req.acceptsLanguages(['fr', 'en']);
return acceptedLanguages || 'fr'; // Default to 'fr' if no match is found
}
function run() {
const port = process.env.PORT || 4000;
const server = express();
// Redirect root requests to the preferred language
server.get('/', (req, res) => {
const lang = getPreferredLanguage(req);
res.redirect(`/${lang}`);
});
// Serve the language-specific servers
server.use('/fr', serverFr);
server.use('/en', serverEn);
// Handle unmatched routes
server.use((req, res) => {
res.status(404).send('Page not found');
});
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
run();
The server.ts that I'm currently using
import { APP_BASE_HREF } from '@angular/common';
import { CommonEngine, isMainModule } from '@angular/ssr/node';
import express from 'express';
import { dirname, join, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import bootstrap from './main.server';
import { LOCALE_ID } from '@angular/core';
import { REQUEST, RESPONSE } from './express.tokens';
const serverDistFolder = dirname(fileURLToPath(import.meta.url));
const indexHtml = join(serverDistFolder, 'index.server.html');
const app = express();
const commonEngine = new CommonEngine();
// Function to detect the locale from the request
function getLocale(req: express.Request): string {
const supportedLocales = ['fr', 'en']; // Add your supported locales here
const localeFromUrl = req.originalUrl.split('/')[1]; // Extract locale from URL
return supportedLocales.includes(localeFromUrl) ? localeFromUrl : 'en'; // Default to 'en'
}
// Serve static files from the correct localized folder
app.get(
'**',
(req, res, next) => {
const lang = getLocale(req);
const browserDistFolder = resolve(serverDistFolder, `../../browser/${lang}`);
express.static(browserDistFolder, {
maxAge: '1y',
index: 'index.html'
})(req, res, next);
}
);
// Handle all other requests by rendering the Angular application
app.get('**', (req, res, next) => {
const { protocol, originalUrl, headers } = req;
const lang = getLocale(req);
const langPath = `/${lang}/`;
const browserDistFolder = resolve(serverDistFolder, `../../browser/${lang}`);
commonEngine
.render({
bootstrap,
documentFilePath: indexHtml,
url: `${protocol}://${headers.host}${originalUrl}`,
publicPath: browserDistFolder,
providers: [
{ provide: APP_BASE_HREF, useValue: langPath },
{ provide: LOCALE_ID, useValue: lang },
{ provide: RESPONSE, useValue: res },
{ provide: REQUEST, useValue: req },
],
})
.then((html) => res.send(html))
.catch((err) => next(err));
});
// Start the server
if (isMainModule(import.meta.url)) {
const port = process.env['PORT'] || 4000;
app.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
export default app;
I followed this post and the related links to implement i18n on Angular 19 with SSR and ended up with the same TypeError: Cannot read properties of undefined (reading 'method')
error.
Since I didn't understand what the Solution on the previous Answer meant doing I searched a bit more for it and found the following gist with the code that fixed this problem.
https://gist.github/agarciar/4645d32d125db8e93599d4fe152979c1
I was missing the update to the server.ts
file.
import { APP_BASE_HREF } from '@angular/common';
import { CommonEngine } from '@angular/ssr';
import express from 'express';
import { fileURLToPath } from 'node:url';
import { basename, dirname, join, resolve } from 'node:path';
import bootstrap from './src/main.server';
import { LOCALE_ID } from '@angular/core';
import { REQUEST, RESPONSE } from '@animajobs/express.tokens';
export function app(): express.Express {
const server = express();
const serverDistFolder = dirname(fileURLToPath(import.meta.url));
const lang = basename(serverDistFolder);
const langPath = `/${lang}/`;
const browserDistFolder = resolve(serverDistFolder, '../../browser');
const indexHtml = join(serverDistFolder, 'index.server.html');
const commonEngine = new CommonEngine();
server.set('view engine', 'html');
server.set('views', browserDistFolder);
// Serve static files from /browser
server.get(
`*.*`,
express.static(browserDistFolder + langPath, {
maxAge: '1y',
})
);
// All regular routes use the Angular engine
server.get(`*`, (req, res, next) => {
const { protocol, originalUrl, headers } = req;
commonEngine
.render({
bootstrap,
documentFilePath: indexHtml,
url: `${protocol}://${headers.host}${originalUrl}`,
publicPath: browserDistFolder,
providers: [
{ provide: APP_BASE_HREF, useValue: langPath },
{ provide: LOCALE_ID, useValue: lang },
{ provide: RESPONSE, useValue: res },
{ provide: REQUEST, useValue: req },
],
})
.then((html) => res.send(html))
.catch((err) => next(err));
});
return server;
}
it's help me a lot to config angular 19 ssr on Cpanel . Thank you !
import express from 'express';
import fs from 'fs';
import path from 'path';
import { createApp as createAppRo } from './dist/folder/server/ro/server.mjs';
import { createApp as createAppEn } from './dist/folder/server/en/server.mjs';
import { createApp as createAppRu } from './dist/folder/server/ru/server.mjs';
const logFile = fs.createWriteStream(path.join(process.cwd(), 'server.log'), { flags: 'a' });
const originalLog = console.log;
console.log = function() {
logFile.write(new Date().toISOString() + ': ' + Array.from(arguments).join(' ') + '\n');
originalLog.apply(console, arguments);
};
const mainApp = express();
mainApp.use('/en', (req, res, next) => {
console.log('Accessing English route');
createAppEn('en')(req, res, next);
});
mainApp.use('/ru', (req, res, next) => {
console.log('Accessing Russian route');
createAppRu('ru')(req, res, next);
});
mainApp.use('/', (req, res, next) => {
console.log('Accessing root route (RO)');
createAppRo('ro')(req, res, next);
});
const port = process.env.PORT || 3000;
mainApp.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
export default mainApp;
本文标签: internationalizationAngular 19 SSR with i18n alongsideStack Overflow
版权声明:本文标题:internationalization - Angular 19: SSR with i18n alongside - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741540594a2384298.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论