Webpack Favicon Guide

Master favicon setup in Webpack: CopyWebpackPlugin, FaviconsWebpackPlugin, public path configuration, and asset optimization strategies.

Webpack Favicon Setup

1. Choose Plugin

Copy or Generate

2. Configure

webpack.config.js

3. Build

Auto-copied

Method 1: CopyWebpackPlugin (Simple)

Copy Existing Favicons

1. Install Plugin

npm install --save-dev copy-webpack-plugin

2. File Structure

my-webpack-app/
  src/
    favicons/           ? Place all favicons here
      favicon.ico
      favicon-16x16.png
      favicon-32x32.png
      apple-touch-icon.png
      android-chrome-192x192.png
      android-chrome-512x512.png
      site.webmanifest
    index.html
    index.js
  webpack.config.js

3. webpack.config.js

const CopyPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.js',
  output: {
    path: __dirname + '/dist',
    filename: 'bundle.js'
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new CopyPlugin({
      patterns: [
        { 
          from: 'src/favicons', 
          to: '', // Copy to dist root
          globOptions: {
            ignore: ['**/.DS_Store']
          }
        }
      ]
    })
  ]
};

4. Update src/index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Webpack App</title>
    
    <!-- Favicons -->
    <link rel="icon" type="image/x-icon" href="favicon.ico">
    <link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png">
    <link rel="apple-touch-icon" href="apple-touch-icon.png">
    <link rel="manifest" href="site.webmanifest">
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>
Pros: Simple, full control, works with existing favicon sets.

Method 2: FaviconsWebpackPlugin (Auto-Generate)

Automatic Generation from Source Image

1. Install Plugin

npm install --save-dev favicons-webpack-plugin

2. webpack.config.js (Full Configuration)

const FaviconsWebpackPlugin = require('favicons-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new FaviconsWebpackPlugin({
      logo: './src/logo.png', // Source image (512x512 or larger)
      mode: 'webapp', // 'webapp' | 'light' | 'auto'
      devMode: 'webapp', // Same in development
      favicons: {
        appName: 'My Webpack App',
        appDescription: 'My awesome webpack application',
        developerName: 'Your Name',
        developerURL: null,
        background: '#ffffff',
        theme_color: '#333333',
        icons: {
          android: true,      // Android icons
          appleIcon: true,    // Apple touch icons
          appleStartup: false, // Apple startup images
          coast: false,       // Opera Coast
          favicons: true,     // Regular favicons
          firefox: false,     // Firefox OS
          windows: true,      // Windows tiles
          yandex: false       // Yandex browser
        }
      }
    })
  ]
};

3. Minimal Configuration

new FaviconsWebpackPlugin({
  logo: './src/logo.png',
  // Plugin will auto-generate all common sizes
})
Note: Plugin automatically injects favicon links into HTML via HtmlWebpackPlugin.

What Gets Generated

  • ? favicon.ico (multi-size)
  • ? favicon-16x16.png, favicon-32x32.png
  • ? Apple touch icons (all sizes)
  • ? Android chrome icons (192x192, 512x512)
  • ? manifest.json
  • ? browserconfig.xml (Windows tiles)
  • ? Automatic HTML injection

Public Path Configuration

CDN & Subdirectory Deployment

For CDN Deployment

module.exports = {
  output: {
    publicPath: 'https://cdn.example.com/assets/'
  },
  plugins: [
    new FaviconsWebpackPlugin({
      logo: './src/logo.png',
      publicPath: 'https://cdn.example.com/assets/',
      outputPath: 'favicons/' // Within dist
    })
  ]
};

For Subdirectory

module.exports = {
  output: {
    publicPath: '/my-app/'
  },
  plugins: [
    new CopyPlugin({
      patterns: [
        { from: 'src/favicons', to: '' }
      ]
    })
  ]
};

Build & Production

Build Commands

Development

npm run dev
# or
webpack serve --mode development

Production Build

npm run build
# or
webpack --mode production

Verify Output

  1. Check dist/ folder contains favicon files
  2. Open dist/index.html and verify favicon links
  3. Test locally: npx serve dist
  4. Check browser DevTools ? Network ? favicon requests

Webpack Favicon Best Practices

? Best Practices

  • Use CopyPlugin for pre-generated favicons
  • Use FaviconsWebpackPlugin for auto-generation
  • Provide high-res source image (512x512+)
  • Configure publicPath for CDN
  • Test production build locally
  • Verify HTML injection works
  • Enable caching in production
  • Use HtmlWebpackPlugin for injection

? Common Mistakes

  • Forgetting to install required plugins
  • Wrong paths in CopyPlugin patterns
  • Not using HtmlWebpackPlugin
  • Missing publicPath configuration
  • Low-resolution source images
  • Not testing production build
  • Hardcoding paths in HTML
  • Ignoring cache busting

Generate Webpack-Ready Favicons

Create optimized favicon packages for Webpack projects

Generate Favicons

Related Articles

An unhandled error has occurred. Reload 🗙