Angular Favicon Complete Guide

Master favicons in Angular: implementation for Angular 17+, dynamic favicon updates, SSR/SSG considerations, PWA setup, and best practices for modern Angular applications.

Quick Reference

Angular CLI

Add to /src/

Configure in angular.json

SSR/SSG

Use Meta service

Configure in server files

PWA

Use @angular/pwa

Auto-generates manifest

Standard Angular Implementation

Angular CLI Project Setup

Step 1: Add Favicons to /src/ Folder

/src/
  favicon.ico
  assets/
    icons/
      favicon-16x16.png
      favicon-32x32.png
      favicon-96x96.png
      favicon-512x512.png
      apple-touch-icon.png
      android-chrome-192x192.png
      android-chrome-512x512.png

Step 2: Update index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Angular App</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  
  <!-- Favicons -->
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link rel="icon" type="image/png" sizes="16x16" href="assets/icons/favicon-16x16.png">
  <link rel="icon" type="image/png" sizes="32x32" href="assets/icons/favicon-32x32.png">
  <link rel="icon" type="image/png" sizes="96x96" href="assets/icons/favicon-96x96.png">
  <link rel="icon" type="image/png" sizes="512x512" href="assets/icons/favicon-512x512.png">
  <link rel="apple-touch-icon" sizes="180x180" href="assets/icons/apple-touch-icon.png">
</head>
<body>
  <app-root></app-root>
</body>
</html>

Step 3: Configure angular.json (Optional)

// angular.json
{
  "projects": {
    "your-app": {
      "architect": {
        "build": {
          "options": {
            "assets": [
              "src/favicon.ico",
              "src/assets",
              {
                "glob": "**/*",
                "input": "src/assets/icons",
                "output": "/assets/icons"
              }
            ]
          }
        }
      }
    }
  }
}
Angular Advantage: Files in assets array are automatically copied to output directory during build.

Dynamic Favicon Service

Change Favicon Programmatically

Create Favicon Service

// src/app/services/favicon.service.ts
import { Injectable, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';

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

  setFavicon(href: string): void {
    const link = this.document.querySelector("link[rel*='icon']") as HTMLLinkElement;
    if (link) {
      link.href = href;
    } else {
      const newLink = this.document.createElement('link');
      newLink.rel = 'icon';
      newLink.href = href;
      this.document.head.appendChild(newLink);
    }
  }

  setFaviconByType(type: 'default' | 'notification' | 'error'): void {
    const icons = {
      default: 'favicon.ico',
      notification: 'assets/icons/favicon-notification.ico',
      error: 'assets/icons/favicon-error.ico'
    };
    this.setFavicon(icons[type]);
  }
}

Usage in Component

// app.component.ts
import { Component, inject } from '@angular/core';
import { FaviconService } from './services/favicon.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent {
  private faviconService = inject(FaviconService);

  ngOnInit() {
    // Change favicon on notification
    this.faviconService.setFaviconByType('notification');
    
    // Or use custom path
    this.faviconService.setFavicon('assets/icons/custom-favicon.ico');
  }
}

Notification Badge Service (Advanced)

// favicon-badge.service.ts
import { Injectable, Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';

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

  drawBadge(count: number): void {
    const canvas = this.document.createElement('canvas');
    canvas.width = 32;
    canvas.height = 32;
    const ctx = canvas.getContext('2d');

    if (!ctx) return;

    // Load original favicon
    const img = new Image();
    img.onload = () => {
      ctx.drawImage(img, 0, 0, 32, 32);
      
      if (count > 0) {
        // Badge background
        ctx.fillStyle = '#FF0000';
        ctx.beginPath();
        ctx.arc(24, 8, 8, 0, 2 * Math.PI);
        ctx.fill();
        
        // Badge text
        ctx.fillStyle = '#FFFFFF';
        ctx.font = 'bold 12px Arial';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillText(count > 9 ? '9+' : count.toString(), 24, 8);
      }
      
      this.updateFavicon(canvas.toDataURL());
    };
    img.src = 'favicon.ico';
  }

  private updateFavicon(dataUrl: string): void {
    let link = this.document.querySelector("link[rel*='icon']") as HTMLLinkElement;
    if (!link) {
      link = this.document.createElement('link');
      link.rel = 'icon';
      this.document.head.appendChild(link);
    }
    link.href = dataUrl;
  }

  reset(): void {
    this.drawBadge(0);
  }
}

Server-Side Rendering (SSR/SSG)

Angular Universal Considerations

SSR-Safe Favicon Service

// favicon.service.ts (SSR-safe)
import { Injectable, Inject, PLATFORM_ID } from '@angular/core';
import { DOCUMENT, isPlatformBrowser } from '@angular/common';

@Injectable({
  providedIn: 'root'
})
export class FaviconService {
  constructor(
    @Inject(DOCUMENT) private document: Document,
    @Inject(PLATFORM_ID) private platformId: Object
  ) {}

  setFavicon(href: string): void {
    // Only execute in browser
    if (isPlatformBrowser(this.platformId)) {
      const link = this.document.querySelector("link[rel*='icon']") as HTMLLinkElement;
      if (link) {
        link.href = href;
      }
    }
  }
}

Meta Tags with Meta Service

// Using Angular Meta service for SEO
import { Component, OnInit, inject } from '@angular/core';
import { Meta } from '@angular/platform-browser';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
  private meta = inject(Meta);

  ngOnInit() {
    // Add meta tags for favicons (SSR-compatible)
    this.meta.addTags([
      { name: 'msapplication-TileColor', content: '#2b5797' },
      { name: 'theme-color', content: '#ffffff' }
    ]);
  }
}
Important: Always check isPlatformBrowser before manipulating DOM in SSR/SSG applications to avoid server-side errors.

PWA Favicon Configuration

Progressive Web App Icons

Step 1: Add PWA Support

ng add @angular/pwa

Step 2: Configure manifest.webmanifest

// src/manifest.webmanifest
{
  "name": "My Angular App",
  "short_name": "AngularApp",
  "theme_color": "#1976d2",
  "background_color": "#fafafa",
  "display": "standalone",
  "scope": "./",
  "start_url": "./",
  "icons": [
    {
      "src": "assets/icons/icon-72x72.png",
      "sizes": "72x72",
      "type": "image/png",
      "purpose": "maskable any"
    },
    {
      "src": "assets/icons/icon-96x96.png",
      "sizes": "96x96",
      "type": "image/png",
      "purpose": "maskable any"
    },
    {
      "src": "assets/icons/icon-128x128.png",
      "sizes": "128x128",
      "type": "image/png",
      "purpose": "maskable any"
    },
    {
      "src": "assets/icons/icon-144x144.png",
      "sizes": "144x144",
      "type": "image/png",
      "purpose": "maskable any"
    },
    {
      "src": "assets/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png",
      "purpose": "maskable any"
    },
    {
      "src": "assets/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png",
      "purpose": "maskable any"
    }
  ]
}

Step 3: Link Manifest in index.html

<link rel="manifest" href="manifest.webmanifest">
<meta name="theme-color" content="#1976d2">

Angular 17+ Standalone Components

Modern Angular Approach

Standalone Favicon Service

// favicon.service.ts
import { Injectable, inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';

@Injectable({
  providedIn: 'root'
})
export class FaviconService {
  private document = inject(DOCUMENT);

  setFavicon(href: string): void {
    const link = this.document.querySelector("link[rel*='icon']") as HTMLLinkElement;
    if (link) {
      link.href = href;
    } else {
      const newLink = this.document.createElement('link');
      newLink.rel = 'icon';
      newLink.href = href;
      this.document.head.appendChild(newLink);
    }
  }
}

// Usage in standalone component
import { Component, inject, OnInit } from '@angular/core';
import { FaviconService } from './services/favicon.service';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [],
  templateUrl: './app.component.html'
})
export class AppComponent implements OnInit {
  private faviconService = inject(FaviconService);

  ngOnInit() {
    this.faviconService.setFavicon('assets/icons/favicon-new.ico');
  }
}

Angular Favicon Best Practices

? Recommendations

  • Use @Inject(DOCUMENT) for DOM access
  • Check isPlatformBrowser for SSR
  • Place favicons in /src/ or /src/assets/
  • Configure assets in angular.json
  • Use Angular services for dynamic updates
  • Add PWA support for app icons
  • Test SSR build (npm run build:ssr)
  • Leverage dependency injection

? Common Mistakes

  • Direct DOM manipulation without DOCUMENT token
  • Not checking platform in SSR apps
  • Forgetting to add to angular.json assets
  • Using window object directly
  • Ignoring PWA manifest requirements
  • Not testing production build
  • Hardcoding paths instead of using assets folder
  • Missing providedIn: 'root' in services

Troubleshooting

Solutions:
  • Ensure favicon.ico is in /src/ folder
  • Check path in index.html is correct
  • Verify angular.json includes favicon in assets
  • Clear browser cache (Ctrl+Shift+R)
  • Restart Angular dev server (ng serve)

Fixes:
  • Use @Inject(PLATFORM_ID) and isPlatformBrowser
  • Avoid direct document or window access
  • Use Angular's DOCUMENT token
  • Test with npm run build:ssr && npm run serve:ssr

Solutions:
  • Verify service is injected correctly
  • Check browser console for errors
  • Add cache busting: href + '?v=' + Date.now()
  • Ensure code runs in browser (not server)

Generate Angular-Ready Favicons

Create complete favicon package optimized for Angular applications

Generate for Angular

Related Articles

An unhandled error has occurred. Reload 🗙