Useful Development

Angular: configurable lazy loaded libraries

posted on Feb 16, 2020

Using forRoot to pass configuration options into a library is a well used pattern in Angular.

      message: environment.message

If the library is lazy loaded though there is no opportunity to do this as the library will now be dynamically imported by the router.

const routes: Routes = [
    path: 'test',
    loadChildren: () => import('./test/test.module').then(m => m.TestModule)

There is a way (hack?) round this which I'll show below. If you want to skip to the code then it's here.

Set up the project

To get started create a project, an app (web-app) and the lazy loaded feature library (test-lib).

ng n ng-configurable-lazy-lib-sample --interactive=false --createApplication=false --routing=true
cd ng-configurable-lazy-lib-sample
ng g application web-app --routing=true --style=scss
ng g library test-lib

Make the library configurable

For this sample we want test-lib to have a setting, which will allow the message displayed by the test component to be set by the consuming application.

Add the following files under the test-lib/lib folder.

export interface TestlLibConfig {
  message: string;
import { InjectionToken } from '@angular/core';
import { TestLibConfig } from './test-lib-config';

export const TEST_LIB_CONFIG = new InjectionToken(

This is the new part. Instead of using forRoot add a static settings property to the module along with a factory to provide the TEST_LIB_CONFIG, returning the settings.

export function SettingFactory() {
  return TestLibModule.settings;

// @dynamic
  declarations: [TestComponent],
  imports: [CommonModule, TestLibRoutingModule],
  providers: [
      provide: TEST_LIB_CONFIG,
      useFactory: SettingFactory
export class TestLibModule {
  static settings: TestLibConfig;

  constructor() {}

Use a configuration property in a component

Import the config into TestLibComponent and display the message property.

  selector: 'lib-test-lib',
  template: `
    <h2>Configurable message: {{ message }}</h2>
  styles: []
export class TestLibComponent implements OnInit {
  message: string;
  constructor(@Inject(TEST_LIB_CONFIG) private testLibConfig: TestLibConfig) {}

  ngOnInit() {
    this.message = this.testLibConfig.message;

Add routing to the library and update the library api

Add a file test-lib-routing.module.ts under the lib folder as below.

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { TestLibComponent } from './test-lib.component';

const routes: Routes = [
  { path: 'test', component: TestLibComponent },
    path: '**',
    redirectTo: 'test'

  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
export class TestLibRoutingModule {}

Export all the new files by adding them to public-api.ts.

export * from './lib/test-lib-config';
export * from './lib/test-lib-config.token';
export * from './lib/test-lib-routing.module';
export * from './lib/test-lib.component';
export * from './lib/test-lib.module';
export * from './lib/test-lib.service';

Lazy load the library in the app

Set up the route to the test-lib in app-routing.module.ts and set the library settings property.

const routes: Routes = [
    path: 'test-lib',
    loadChildren: () =>
      import('test-lib').then(m => {
        m.TestLibModule.settings = {
          message: environment.message

        return m.TestLibModule;
    path: '**',
    redirectTo: 'test-lib'

Replace the boilerplate app.component markup.

<h1>configurable lazy lib</h1>

Test it out

Build the library and the app. The run the app

ng build test-lib
ng build web-app
ng s

Now run it and if everything has gone to plan you will see that that message value set in the app is displayed.