Skip to content

SSR provider not working in angular dev-server 18.0.4 when provided in commonEngine.render() #28152

@jaibeales

Description

@jaibeales

Which @angular/* package(s) are the source of the bug?

core

Is this a regression?

No

Description

We have a need to provide some config at runtime (not ideal but is part of a multi environment deployment process), with a recent foray into SSR we have decided to this via a provider during bootstrapping. Basically the spa downloads a config.json, the server reads it from file locally. This works using node and in the client, it doesn't work with the angular dev-server (ng serve).

This is how it is done on the server (see APP_CONFIG):

export function app(): express.Express {
  const server = express();
  const serverDistFolder = dirname(fileURLToPath(import.meta.url));
  const browserDistFolder = resolve(serverDistFolder, '../browser');
  const indexHtml = join(serverDistFolder, 'index.server.html');

  const config = loadConfig(browserDistFolder);

  const commonEngine = new CommonEngine();

  server.set('view engine', 'html');
  server.set('views', browserDistFolder);

  // Example Express Rest API endpoints
  // server.get('/api/**', (req, res) => { });
  // Serve static files from /browser
  server.get(
    '**',
    express.static(browserDistFolder, {
      maxAge: '1y',
      index: 'index.html',
    }),
  );

  // All regular routes use the Angular engine
  server.get('**', (req, res, next) => {
    const { protocol, originalUrl, baseUrl, headers } = req;

    commonEngine
      .render({
        bootstrap,
        documentFilePath: indexHtml,
        url: `${protocol}://${headers.host}${originalUrl}`,
        publicPath: browserDistFolder,
        providers: [
          { provide: APP_BASE_HREF, useValue: baseUrl },
          { provide: 'APP_CONFIG', useValue: config },
        ],
      })
      .then((html) => res.send(html))
      .catch((err) => next(err));
  });

  return server;
}

This is the main.ts for the client side provider:

fetch('/assets/config/config.json')
  .then((response) => response.json())
  .then((serverConfig) => {
    // Create a new config object with the server config
    const serverAppConfig: ApplicationConfig = {
      providers: [{ provide: 'APP_CONFIG', useValue: serverConfig }],
    };

    const mergedConfig = mergeApplicationConfig(appConfig, serverAppConfig);
    bootstrapApplication(AppComponent, mergedConfig).catch((err) => console.error('Error during bootstrap:', err));
  })
  .catch((err) => {
    console.error('Failed to load configuration:', err);
    // Fallback to bootstrapping with just the original app config
    bootstrapApplication(AppComponent, appConfig).catch((err) => console.error('Error during bootstrap:', err));
  });

Please provide a link to a minimal reproduction of the bug

No response

Please provide the exception or error you saw

[vite] Internal server error: R3InjectorError(Standalone[_AppComponent])[_ConfigService -> _ConfigService -> APP_CONFIG -> APP_CONFIG]: 
  NullInjectorError: No provider for APP_CONFIG!

Please provide the environment you discovered this bug in (run ng version)

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1800.5
@angular-devkit/build-angular   18.0.5
@angular-devkit/core            18.0.5
@angular-devkit/schematics      18.0.5
@angular/cdk                    16.2.14
@angular/cli                    18.0.5
@angular/flex-layout            13.0.0-beta.38
@angular/material               16.2.14
@angular/platform-server        18.0.7
@angular/ssr                    18.0.5
@schematics/angular             18.0.5
rxjs                            7.8.1
typescript                      5.4.5
webpack                         5.91.0
zone.js                         0.14.4

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions