About my blog

I write about the technical and non-technical aspects of software development

How it works

Microsoft ASP.NETASP.Net
BlogEngine.NET BlogEngine.NET
Azure DevOpsAzure DevOps

Contact info

 Email
 Contact

Follow me

Prod-20240407.1

platformBrowserDynamic with Angular Universal

Using platformBrowserDynamic with Angular Universal is a bit of a hack. All we are doing is providing configuration to the application server module so that it has configuration server-side before platformBrowserDynamic can load it on the client.

platformBrowserDynamic with Angular Universal

In the previous article I described how the platformBrowserDynamic method can be provided with runtime configuration in client-side Angular applications.

Now we'll adapt the method so it also works with Angular Universal and server-side rendering (SSR) and even server-side generation (SSG).

Strictly speaking this process is simply about providing configuration to the AppServerModule (and in turn AppModule). As far as SSR/SSG goes this is a necessary step, because the clue is in the name: platformBrowserDynamic - the method is specifically for browser i.e. client-side, execution.

With that in mind, all we actually need is to provide configuration for server-side on bootstrap, then when the application is hydrated on the client, the same configuration can be loaded via platformBrowserDynamic.

So, after installing Angular Universal (the process is described here), the first thing we need to do is ensure that configuration is available to the bootstrapping process in  app.server.module.ts.


import { APP_CONFIG, AppConfig } from './app.config';

@NgModule({
  imports: [
    AppModule,
    ServerModule,
  ],
  providers: [
    {
      provide: APP_CONFIG,
      useFactory: (config: AppConfig) => {
        config = require("../assets/config.json");
        console.debug(`Node server loaded app config for prerendering. Env: ${config.env}`);
        return config;
      }
    }
  ],
  bootstrap: [AppComponent],
})
export class AppServerModule {}

When we run this

npm run dev:ssr

We can see the output logged from the app.component.ts:


Node server loaded app config for prerendering. Env: Dev
AppComponent constructor: Dev
NgxLogger browser level configured by runtime configuration: 'INFO'
2024-01-16T21:02:25.349Z INFO [app.component.ts:31:17] Info output
2024-01-16T21:02:25.602Z LOG [app.component.ts:32:17] Log output
2024-01-16T21:02:25.789Z WARN [app.component.ts:33:17] Warn output
2024-01-16T21:02:25.968Z ERROR [app.component.ts:34:17] Error output
2024-01-16T21:02:26.121Z FATAL [app.component.ts:35:17] Fatal output
AppComponent onInit
{
 env: 'Dev',
 apiBaseUrl: 'https://collectionapi.metmuseum.org/public/collection/v1',
 activeTheme: 'solution-b',
 logger: { browserLogLevel: 2, serverLogLevel: 7, serverLoggingUrl: null },
 buildRef: '1.0.0.0B-DEV'
}

Recall the default configuration in the LoggerConfig class:


export class LoggerConfig {
  browserLogLevel: NgxLoggerLevel = NgxLoggerLevel.TRACE;
  serverLogLevel: NgxLoggerLevel = NgxLoggerLevel.TRACE;
  serverLoggingUrl: string | undefined;
}

Now consider the following lines from app.component.ts:


console.debug(`NgxLogger browser level configured by runtime configuration: '${NgxLoggerLevel[this.logger.level]}'`);
this.logger.trace(`Trace output`);
this.logger.debug(`Debug output`);
this.logger.info(`Info output`);
this.logger.log(`Log output`);
this.logger.warn(`Warn output`);
this.logger.error(`Error output`);
this.logger.fatal(`Fatal output`);

Notice how the TRACE and DEBUG lines are not shown in the output?

It's clear that the value of browserLevel is being updated to INFO, and is in fact the value set in assets/config.json, thus preventing output of TRACE and DEBUG, and proving that runtime configuration is working:


{
  "env": "Dev",
  "apiBaseUrl": "https://collectionapi.metmuseum.org/public/collection/v1",
  "activeTheme": "solution-b",
  "logger": {
    "browserLogLevel": 2,
    "serverLogLevel": 7,
    "serverLoggingUrl": null
  },
  "buildRef": "1.0.0.0B-DEV"
}	

This concludes my series of articles about Angular runtime configuration. I hope it is helpful.

Happy coding!


You Might Also Like


Would you like to share your thoughts?

Your email address will not be published. Required fields are marked *

Comments are closed