You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 19 SSR集成i18n报错,寻求标准集成方案

Angular 19 SSR 与 i18n 集成问题

此前按照《Angular 17: SSR with i18n alongside》的步骤实现了 SSR 与 i18n 集成,升级至 Angular 19 后该方案失效。修改 proxy-server.mjs(代码如下)后,出现错误:TypeError: Cannot read properties of undefined (reading 'method')。请问 Angular 19 是否有标准的 i18n 集成方式?

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();

先解决当前错误问题

你遇到的 TypeError 是因为 Angular 19 调整了 SSR 服务器的导出格式:语言包的 server.mjs 不再导出可直接调用的函数,而是导出一个 app 对象,需直接传给 server.use,不能加括号调用。同时建议统一使用 ES 模块语法,避免混合 CommonJS 和 ES 模块导致的冲突。

修改后的 proxy-server.mjs 代码:

import { app as serverEn } from './server/en/server.mjs';
import { app as serverFr } from './server/fr/server.mjs';

import express from 'express';

function getPreferredLanguage(req) {
  const acceptedLanguages = req.acceptsLanguages(['fr', 'en']);
  return acceptedLanguages || 'fr';
}

function run() {
  const port = process.env.PORT || 4000;
  const server = express();

  server.get('/', (req, res) => {
    const lang = getPreferredLanguage(req);
    res.redirect(`/${lang}`);
  });

  // 直接使用导出的 app 对象,无需调用函数
  server.use('/fr', serverFr);
  server.use('/en', serverEn);

  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();

Angular 19 标准的 i18n + SSR 集成方式

Angular 19 内置了更简化的多语言 SSR 支持,无需手动编写代理服务器,步骤如下:

1. 配置 angular.json

在项目配置中定义多语言构建目标,确保每个语言的客户端和 SSR 构建都启用本地化:

"projects": {
  "your-app": {
    "i18n": {
      "sourceLocale": "fr",
      "locales": {
        "en": "src/locale/messages.en.xlf"
      }
    },
    "architect": {
      "build": {
        "configurations": {
          "en": {
            "localize": ["en"],
            "outputPath": "dist/your-app/en"
          },
          "fr": {
            "localize": ["fr"],
            "outputPath": "dist/your-app/fr"
          }
        }
      },
      "server": {
        "configurations": {
          "en": {
            "localize": ["en"],
            "outputPath": "dist/your-app/server/en"
          },
          "fr": {
            "localize": ["fr"],
            "outputPath": "dist/your-app/server/fr"
          }
        }
      }
    }
  }
}

2. 构建多语言包

运行命令构建所有语言的客户端和 SSR 代码:

ng build --configuration=en,fr
ng run your-app:server --configuration=en,fr

3. 统一启动多语言 SSR

使用 @angular/ssr 提供的工具创建统一服务器入口,自动处理语言路由:

import { ngExpressEngine } from '@angular/ssr';
import express from 'express';
import { join } from 'path';
import { AppServerModule } from './src/main.server';
import { APP_BASE_HREF, LOCALE_ID } from '@angular/common';

const app = express();
const port = process.env.PORT || 4000;
const locales = ['fr', 'en'];

// 为每个语言配置静态文件和 SSR 渲染
locales.forEach(locale => {
  const browserDist = join(process.cwd(), `dist/your-app/${locale}/browser`);
  const serverDist = join(process.cwd(), `dist/your-app/server/${locale}`);

  // 托管静态资源
  app.use(`/${locale}`, express.static(browserDist, { maxAge: '1y' }));

  // 配置 SSR 引擎
  app.engine('html', ngExpressEngine({
    bootstrap: AppServerModule,
    providers: [
      { provide: APP_BASE_HREF, useValue: `/${locale}` },
      { provide: LOCALE_ID, useValue: locale }
    ]
  }));

  app.set('view engine', 'html');
  app.set('views', serverDist);

  // 处理语言路由下的所有请求
  app.get(`/${locale}/*`, (req, res) => {
    res.render('index', {
      req,
      res,
      providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }]
    });
  });
});

// 根路径重定向到首选语言
app.get('/', (req, res) => {
  const preferredLang = req.acceptsLanguages(locales) || 'fr';
  res.redirect(`/${preferredLang}`);
});

app.listen(port, () => {
  console.log(`Server listening on http://localhost:${port}`);
});

4. 启动服务器

运行上述入口文件即可,无需手动维护多个语言的服务器实例,完全遵循 Angular 官方规范,后续版本升级兼容性更强。

内容的提问来源于stack exchange,提问作者mbagiella

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 12:28:22