fix(ssr): bootstrap standalone app for CommonEngine
continuous-integration/drone/push Build is passing

Passing EnvironmentProviders via CommonEngine StaticProvider[] dropped
provideZoneChangeDetection, causing ZoneStablePendingTask2 on render.
Use bootstrapApplication + mergeApplicationConfig instead.
This commit is contained in:
miczek committed 2026-10-15 05:19:28 +03:00
1 parent 0b82cbb25f
commit 0a30980105
5 files changed
+34 -36

No files matched your search

+4 -7
View File
@@ -5,7 +5,7 @@ import { CommonEngine } from '@angular/ssr/node';
import express from 'express';
import { existsSync } from 'node:fs';
import { join } from 'node:path';
import AppServerModule from './src/main.server';
import bootstrap from './src/main.server';
const STRAVA_API_BASE = 'https://www.strava.com/api/v3';
const FACEIT_API_BASE = 'https://open.faceit.com';
@@ -230,11 +230,8 @@ export function app(): express.Express {
commonEngine
.render({
bootstrap: AppServerModule.bootstrap,
providers: [
...AppServerModule.providers,
{ provide: APP_BASE_HREF, useValue: baseUrl },
] as unknown as import('@angular/core').StaticProvider[],
bootstrap,
providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }],
documentFilePath: indexHtml,
url: `${protocol}://${headers.host}${originalUrl}`,
publicPath: distFolder,
@@ -262,4 +259,4 @@ if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
run();
}
export default AppServerModule.bootstrap;
export default bootstrap;
+10
View File
@@ -0,0 +1,10 @@
import { ApplicationConfig, mergeApplicationConfig } from '@angular/core';
import { provideServerRendering } from '@angular/platform-server';
import { appConfig } from './app.config';
const serverConfig: ApplicationConfig = {
providers: [provideServerRendering()],
};
/** Browser + server providers for SSR bootstrap. */
export const config = mergeApplicationConfig(appConfig, serverConfig);
+8 -2
View File
@@ -1,6 +1,11 @@
import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import {
provideHttpClient,
withFetch,
withInterceptors,
} from '@angular/common/http';
import { provideClientHydration } from '@angular/platform-browser';
import { routes } from './app.routes';
import { apiInterceptor } from './core/interceptors/api.interceptor';
@@ -8,7 +13,8 @@ export const appConfig: ApplicationConfig = {
providers: [
provideZoneChangeDetection({ eventCoalescing: true }),
provideRouter(routes),
provideHttpClient(withInterceptors([apiInterceptor])),
provideHttpClient(withFetch(), withInterceptors([apiInterceptor])),
provideClientHydration(),
],
};
+2 -12
View File
@@ -1,12 +1,2 @@
import { provideServerRendering } from '@angular/platform-server';
import { AppComponent } from './app.component';
import { appConfig } from './app.config';
export const AppServerModule = {
bootstrap: AppComponent,
providers: [
...appConfig.providers,
provideServerRendering(),
],
};
// Kept for older import paths; prefer src/main.server.ts.
export { config as default } from './app.config.server';
+10 -15
View File
@@ -1,17 +1,12 @@
export { AppServerModule as default } from './app/app.server';
import {
bootstrapApplication,
BootstrapContext,
} from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { config } from './app/app.config.server';
/** Standalone SSR bootstrap for CommonEngine. */
const bootstrap = (context: BootstrapContext) =>
bootstrapApplication(AppComponent, config, context);
export default bootstrap;