4

Hey is it possible to load Fonts dynamically with Angular 2.4? I tried the following but it does not work.

<style>
  @font-face { font-family: '{{ font.name }}';
    src: url('{{ font.url }}')  format('woff'); }
</style>
@Component({
  selector: 'nova-font-loader',
  templateUrl: './template.html'
})
export class NovaFontLoaderComponent implements OnInit {

  private font;

  constructor() { }

  ngOnInit() {
    this.font = {
      url: 'test.woff',
      name: 'test'
    };
  }

}

It generates the following console output:

GET http://localhost:4200/url(%7B%7B%20font.url%20%7D%7D) 404 (Not Found)

Unhandled Promise rejection: Failed to load url(%7B%7B%20font.url%20%7D%7D) ; Zone: ; Task: Promise.then ; Value: Failed to load url(%7B%7B%20font.url%20%7D%7D)

Dan
  • 12,409
  • 3
  • 50
  • 87
Andre Steudel
  • 113
  • 1
  • 7

2 Answers2

5

You can create a compononent for each font-style, and import in your root component conforms the condition:

Example for Roboto.

Component

Note: encapsulation: ViewEncapsulation.None is very important for this case.

import { Component, OnInit, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'app-font-roboto',
  templateUrl: './font-roboto.component.html',
  encapsulation: ViewEncapsulation.None,
  styleUrls: ['./font-roboto.component.scss']
})
export class FontRobotoComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

SCSS

@font-face {
    font-family: 'Roboto';
    src: url("/assets/fonts/Roboto/Roboto-Regular.eot");
    /* IE9 Compat Modes */
    src: url("/assets/fonts/Roboto/Roboto-Regular.eot?#iefix") format('embedded-opentype'), /* IE6-IE8 */
    url('/assets/fonts/Roboto/Roboto-Regular.ttf') format('truetype'), /* Safari, Android, iOS */
}

@font-face {
    font-family: 'RobotoBold';
    src: url("/assets/fonts/Roboto/Roboto-Bold.eot");
    /* IE9 Compat Modes */
    src: url("/assets/fonts/Roboto/Roboto-Bold.eot?#iefix") format('embedded-opentype'), /* IE6-IE8 */
    url('/assets/fonts/Roboto/Roboto-Bold.ttf') format('truetype'), /* Safari, Android, iOS */
}

body { 
    font-family: 'Roboto', sans-serif;
}

Root component logic

Template [HTML]

<div [ngSwitch]="fontType">
   <app-font-roboto *ngSwitchCase="'Roboto'"></app-font-roboto>
</div>

Component

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  fontType: string;

  ngOnInit(): void {
    this.fontType = 'Roboto';
  }
}

Just add your application logic to get the current font and add new nodes in switch for each font styles that you need.

Leonardo Oliveira
  • 1,349
  • 1
  • 12
  • 14
  • thanks for your answer but the problem i have is that our clients can upload their own fonts, and so i can not create a component for each possible font :( – Andre Steudel Aug 29 '17 at 14:34
  • 2
    Ok I got it. I would try use jQuery to resolve it, adding the font-family after get the font of current client. Pointing to a static file in site content. – Leonardo Oliveira Aug 29 '17 at 15:26
  • @LeonardoOliveira "I would try use jQuery to resolve it, adding the font-family after get the font of current client. Pointing to a static file in site content." - Could you plz elaborate? – Srikanth Apr 01 '18 at 10:36
  • Can i change dynamically URL in SCSS File like "src: url("/assets/fonts/Roboto/Roboto-Bold.eot");" i want that its make dynamical load url – Urvish Patel Aug 10 '18 at 07:17
5

You can easily do that by injecting css in your dom

const fontUrl = '[get your font url here]';
this.styles = `
@font-face {
  font-family: 'font1';
  src: url(${fontUrl}) format('woff');
}
h1, h2, h3 {
  font-family: font1, sans-serif;
}`

const node = document.createElement('style');
node.innerHTML = this.styles;
document.body.appendChild(node);
Thibaud Lacan
  • 346
  • 1
  • 6
  • 13