Skip to content

Support runtime route extraction/prerendering #33426

@christiaan-lombard

Description

@christiaan-lombard

Command

build

Description

Currently, when configuring @angular/build:application with "outputMode": "server", the build pipeline forces a mandatory "Route Extraction" phase. To map out the routing table and prerender pages, the Angular compiler bootstraps an in-memory instance of the application at build time.
This creates a severe architectural bottleneck for cloud-native applications. In enterprise environments, applications rely on APP_INITIALIZER to load configurations (API base URLs, hostnames, feature flags, api keys, etc.) from environment variables that only exist on the target deployment container at server boot runtime.

Because these variables are completely missing during the CI/CD build phase, the application cannot boot, causing the build to fail with AbortError: Routes extraction was aborted.

The Flaw in Current Workarounds

Currently, developers can bypass this by passing an undocumented internal environment variable: NG_BUILD_PARTIAL_SSR=1. This successfully defers route extraction and prerendering to server boot time. However:

  1. It relies on a brittle, unexposed CLI implementation detail rather than an explicitly supported, first-class feature.
  2. It lacks formal documentation and telemetry.
  3. Developers still lack a clean, native way to differentiate between a build environment and a server execution environment when writing targeted fallback logic.

Describe the solution you'd like

1. Expose extractRoutesAtRuntime as a First-Class Build Option

Provide an official configuration option inside angular.json under the architect.build.options tree. This should promote the underlying behavior of NG_BUILD_PARTIAL_SSR=1 to a stable, supported configuration:

"options": {
  "outputMode": "server",
  "extractRoutesAtRuntime": true
}
  • When false (Default): Route extraction and prerendering happen during ng build (CI/CD phase).
  • When true: The compiler outputs the server and client bundles purely as deployable templates. The Express/Node server handles route extraction and initial layout compilation dynamically when it boots up on the production container, where environment variables are fully present.

2. Introduce isPlatformBuild() for the PLATFORM_ID Token

When developers do need to safely guard code paths during compilation (for example, if a third-party module eagerly evaluates a URL during a standard build run), checking isPlatformServer(platformId) is not granular enough. The compilation phase and the live Node.js Express runtime are both "servers" to Angular.
We propose adding a native utility function alongside isPlatformBrowser and isPlatformServer:

import { PLATFORM_ID, inject } from '@angular/core';
import { isPlatformBuild } from '@angular/common';

@Injectable({ providedIn: 'root' })export class ConfigService {
  private readonly platformId = inject(PLATFORM_ID);

  load() {
    // True ONLY during the ng build compilation/extraction pipeline
    if (isPlatformBuild(this.platformId)) {
      return of(this.getBuildTimeMocks()); 
    }

    // True when running live on the production Node/Express server container
    return this.fetchRuntimeSystemEnvVars(); 
  }
}

Describe alternatives you've considered

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions