Search code examples
angulartypescriptdomangular-universalangular11

I cannot use the document injection with angular universal


I try to use the document property of the DOM to remove and add classes to the html and manage some CSS properties, but when I execute the ng run app:serve-ssr command I get the following problem:

Error

This is my code, it is a service that is in a provider called app-initializer, this is the provider and this is how it is importing in the AppModule.

@Injectable({
  providedIn: 'root',
})
export class ThemeService {
 constructor(@Inject(DOCUMENT) private document: Document) {}

 private loadCss(href: string, id: string): Promise<Event> {
    return new Promise((resolve, reject) => {
      const style = this.document.createElement('link');
      style.rel = 'stylesheet';
      style.href = href;
      style.id = id;
      style.onload = resolve;
      style.onerror = reject;
      this.document.head.append(style);
    });
  }
}

AppInitializerProvider

import { APP_INITIALIZER } from '@angular/core';
import { ThemeService } from './utils/services';

export const AppInitializerProvider = {
  provide: APP_INITIALIZER,
  useFactory: (themeService: ThemeService) => () => {
    return themeService.loadTheme();
  },
  deps: [ThemeService],
  multi: true,
};

App module

// ....
providers: [AppInitializerProvider]
// ....

App version:

  1. Angular CLI: 11.2.7
  2. Node: 14.16.0
  3. Angular: 11.2.8
  4. Test in Google Chrome and Microsoft Edge

Solution

  • Try using appendChild instead, append might not be supported on server side DOM

    this.document.head.appendChild(style);
    

    You could also use Renderer2, which is recommanded when manipulating DOM elements from angular

    this.renderer.appendChild(this.document.head, style);