fix(ssr): manually register engine manifest to fix 404 on all routes
CI Pipeline / backend-test (push) Successful in 9m49s
CI Pipeline / frontend-test (push) Successful in 24s
CI Pipeline / frontend-build (push) Successful in 30s
CI Pipeline / backend-lint (push) Successful in 8s
CI Pipeline / backend-test (pull_request) Successful in 9m38s
CI Pipeline / frontend-test (pull_request) Successful in 23s
CI Pipeline / frontend-build (pull_request) Successful in 31s
CI Pipeline / backend-lint (pull_request) Successful in 10s
CI Pipeline / quality-gate (push) Successful in 2s
CI Pipeline / quality-gate (pull_request) Successful in 3s
CI Pipeline / backend-test (push) Successful in 9m49s
CI Pipeline / frontend-test (push) Successful in 24s
CI Pipeline / frontend-build (push) Successful in 30s
CI Pipeline / backend-lint (push) Successful in 8s
CI Pipeline / backend-test (pull_request) Successful in 9m38s
CI Pipeline / frontend-test (pull_request) Successful in 23s
CI Pipeline / frontend-build (pull_request) Successful in 31s
CI Pipeline / backend-lint (pull_request) Successful in 10s
CI Pipeline / quality-gate (push) Successful in 2s
CI Pipeline / quality-gate (pull_request) Successful in 3s
The Angular 21 builder generates angular-app-engine-manifest.mjs at build time but does NOT inject the import into server.mjs. Without manually importing and registering the manifest via ɵsetAngularAppEngineManifest, AngularNodeAppEngine fails with 'Angular app engine manifest is not set' and every request returns 404. This matches the exact issue reported in PR #14 on staging where nginx starts successfully but returns 'Not Found' for all paths.
This commit is contained in:
1 parent
89cac854ae
commit
1db84a384f
1 file changed
+26
-22
@@ -7,25 +7,22 @@ import {
|
|||||||
import * as http from 'node:http';
|
import * as http from 'node:http';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lazily instantiate AngularNodeAppEngine so the engine boots only when
|
* Manually import and register the Angular app engine manifest.
|
||||||
* the first request arrives. All routes use RenderMode.Server — every
|
* The Angular 21 builder generates angular-app-engine-manifest.mjs at build time
|
||||||
* request triggers on-demand SSR that fetches fresh API data before rendering.
|
* but does NOT automatically inject the import into server.mjs.
|
||||||
|
* Without this, AngularNodeAppEngine fails with "Angular app engine manifest is not set"
|
||||||
|
* and every SSR request returns 404.
|
||||||
*/
|
*/
|
||||||
let appEngine: AngularNodeAppEngine | null = null;
|
// @ts-ignore — generated at build time by @angular/build
|
||||||
function getEngine(): AngularNodeAppEngine {
|
import engineManifest from './angular-app-engine-manifest.mjs';
|
||||||
if (!appEngine) {
|
import { ɵsetAngularAppEngineManifest } from '@angular/ssr';
|
||||||
appEngine = new AngularNodeAppEngine();
|
ɵsetAngularAppEngineManifest(engineManifest);
|
||||||
}
|
|
||||||
return appEngine;
|
const appEngine = new AngularNodeAppEngine();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle incoming requests using the Angular SSR engine.
|
|
||||||
* Every request is rendered on the server with fresh data from the API.
|
|
||||||
*/
|
|
||||||
const requestHandler = createNodeRequestHandler(async (req, res, next) => {
|
const requestHandler = createNodeRequestHandler(async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
const response = await getEngine().handle(req);
|
const response = await appEngine.handle(req);
|
||||||
|
|
||||||
if (response) {
|
if (response) {
|
||||||
await writeResponseToNodeResponse(response, res);
|
await writeResponseToNodeResponse(response, res);
|
||||||
@@ -37,17 +34,24 @@ const requestHandler = createNodeRequestHandler(async (req, res, next) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default requestHandler;
|
|
||||||
|
|
||||||
if (isMainModule(import.meta.url)) {
|
if (isMainModule(import.meta.url)) {
|
||||||
const httpServer = http.createServer();
|
console.log('Node.js SSR server ready');
|
||||||
httpServer.on('request', async (req: http.IncomingMessage, res: http.ServerResponse) => {
|
const server = http.createServer();
|
||||||
requestHandler(req, res, () => {
|
server.on('request', async (req, res) => {
|
||||||
|
try {
|
||||||
|
await requestHandler(req, res, () => {
|
||||||
res.statusCode = 404;
|
res.statusCode = 404;
|
||||||
res.end('Not Found');
|
res.end('Not Found');
|
||||||
});
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('SSR error:', error);
|
||||||
|
res.statusCode = 500;
|
||||||
|
res.end('Internal server error');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
httpServer.listen(4200, () => {
|
server.listen(4200, () => {
|
||||||
console.log(`Node SSR server listening on http://localhost:4200`);
|
console.log('SSR server listening on http://localhost:4200');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export { requestHandler };
|
||||||
Reference in new issue
Block a user