[javascript] Add Favicon with React and Webpack

I am attempting to add a favicon to a React-based website that I made using webpack. It has been a total nightmare to add a favicon and I have tried many solutions to no avail. The latest solution that has been recommended to me is called 'favicons-webpack-plugin' which can be found here: https://github.com/jantimon/favicons-webpack-plugin.

If anyone can tell me what I am doing wrong, your assistance would be greatly appreciated.

I get the following error when I run 'npm run start'

enter image description here

This is my directory structure:

enter image description here

This is my webpack.config.js file:

const path = require('path');
const merge = require('webpack-merge');
const webpack = require('webpack');
const NpmInstallPlugin = require('npm-install-webpack-plugin');
const TARGET = process.env.npm_lifecycle_event;
const FaviconsWebpackPlugin = require('favicons-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanPlugin = require('clean-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
var favicons = require('favicons'),
    source = 'my-logo.png',           // Source image(s). `string`, `buffer` or array of `{ size: filepath }`
    configuration = {
        appName: null,                  // Your application's name. `string`
        appDescription: null,           // Your application's description. `string`
        developerName: null,            // Your (or your developer's) name. `string`
        developerURL: null,             // Your (or your developer's) URL. `string`
        background: "#fff",             // Background colour for flattened icons. `string`
        path: "/",                      // Path for overriding default icons path. `string`
        url: "/",                       // Absolute URL for OpenGraph image. `string`
        display: "standalone",          // Android display: "browser" or "standalone". `string`
        orientation: "portrait",        // Android orientation: "portrait" or "landscape". `string`
        version: "1.0",                 // Your application's version number. `number`
        logging: false,                 // Print logs to console? `boolean`
        online: false,                  // Use RealFaviconGenerator to create favicons? `boolean`
        icons: {
            android: true,              // Create Android homescreen icon. `boolean`
            appleIcon: true,            // Create Apple touch icons. `boolean`
            appleStartup: true,         // Create Apple startup images. `boolean`
            coast: true,                // Create Opera Coast icon. `boolean`
            favicons: true,             // Create regular favicons. `boolean`
            firefox: true,              // Create Firefox OS icons. `boolean`
            opengraph: true,            // Create Facebook OpenGraph image. `boolean`
            twitter: true,              // Create Twitter Summary Card image. `boolean`
            windows: true,              // Create Windows 8 tile icons. `boolean`
            yandex: true                // Create Yandex browser icon. `boolean`
        }
    },
    callback = function (error, response) {
        if (error) {
            console.log(error.status);  // HTTP error code (e.g. `200`) or `null`
            console.log(error.name);    // Error name e.g. "API Error"
            console.log(error.message); // Error description e.g. "An unknown error has occurred"
        }
        console.log(response.images);   // Array of { name: string, contents: <buffer> }
        console.log(response.files);    // Array of { name: string, contents: <string> }
        console.log(response.html);     // Array of strings (html elements)
    };

favicons(source, configuration, callback);
const pkg = require('./package.json');

const PATHS = {
  app: path.join(__dirname, 'app'),
  build: path.join(__dirname, 'build')
};

process.env.BABEL_ENV = TARGET;

const common = {
  entry: {
    app: PATHS.app
  },
  // Add resolve.extensions
  // '' is needed to allow imports without an extension
  // note the .'s before the extension as it will fail to load without them
  resolve: {
    extensions: ['', '.js', '.jsx', '.json']
  },
  output: {
    path: PATHS.build,
    filename: 'bundle.js'
  },
  module: {
    loaders: [
      {
        // Test expects a RegExp! Notethe slashes!
        test: /\.css$/,
        loaders: ['style', 'css'],
        //Include accepts either a path or an array of paths
        include: PATHS.app

      },
      //set up JSX. This accepts js too thanks to RegExp
      {
      test: /\.(js|jsx)$/,
      //enable caching for improved performance during development
      //It uses default OS directory by default. If you need something more custom,
      //pass a path to it. ie: babel?cacheDirectory=<path>
      loaders: [
        'babel?cacheDirectory,presets[]=es2015'
    ],
      //parse only app files Without this it will go thru the entire project.
      //beside being slow this will likely result in an error
      include: PATHS.app
      }
    ]
  }
};

// Default configuration. We will return this if
// Webpack is called outside of npm.
if(TARGET === 'start' || !TARGET){
  module.exports = merge(common, {
    devtool: 'eval-source-map',
    devServer: {
      contentBase: PATHS.build,

      //enable history API fallback so HTML5 HISTORY API based
      // routing works. This is a good default that will come in handy in more
      // complicated setups.
      historyApiFallback: true,
      hot: true,
      inline: true,
      progress: true,

      //display only errors to reduce output amount
      stats: 'errors only',

      //Parse host and port from env so this is easy to customize
      host: process.env.HOST,
      port: process.env.PORT

},

plugins: [
  new webpack.HotModuleReplacementPlugin(),
  new NpmInstallPlugin({
    save: true //--save
  }),
  new FaviconsWebpackPlugin('my-logo.png')

]
});
}

if(TARGET === 'build' || TARGET === 'stats') {
  module.exports = merge(common, {
    entry: {
      vendor: Object.keys(pkg.dependencies).filter(function(v) {
        return v !== 'alt-utils';
      }),
      style: PATHS.style
    },
    output: {
      path: PATHS.build,
      // Output using entry name
      filename: '[name].[chunkhash].js',
      chunkFilename: '[chunkhash].js'
    },
    module: {
      loaders: [
        // Extract CSS during build
        {
          test: /\.css$/,
          loader: ExtractTextPlugin.extract('style', 'css'),
          include: PATHS.app
        }
      ]
    },
    plugins: [
      // Output extracted CSS to a file
      new ExtractTextPlugin('[name].[chunkhash].css'),
      // Extract vendor and manifest files
      new webpack.optimize.CommonsChunkPlugin({
        names: ['vendor', 'manifest']
      }),
      // Setting DefinePlugin affects React library size!
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': '"production"'
      }),
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          warnings: false
        }
      })
    ]
  });
}

This is my server.js file:

/* Global Requires */

const express    = require('express');
const logger     = require('morgan');
const bodyParser = require('body-parser');
const path       = require('path');
const app        = express();
const ReactDOM = require('react-dom')
var favicon = require('serve-favicon');


if(process.env.NODE_ENV === 'development') {
  console.log('in development.');
  require('dotenv').config();
} else {
  console.log('in production.');
}

/* App Config */
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'build')));
app.use(favicon(__dirname + '/public/favicon.ico'));

app.use(logger('dev'));

/* Server Initialization */
app.get('/', (req, res) => res.sendFile('index.html'));
var port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Server initialized on // ${new Date()}`));

This question is related to javascript node.js reactjs webpack favicon

The answer is


The correct answer in the present if you dont use Create React App is the next:

new HtmlWebpackPlugin({
   favicon: "./public/fav-icon.ico"
})

If you use CRA then you can modificate the manifest.json in the public directory


I will give simple steps to add favicon :-)

  • Create your logo and save as logo.png
  • Change logo.png to favicon.ico

    Note : when you save it is favicon.ico make sure it's not favicon.ico.png

  • It might take some time to update

    change icon size in manifest.json if you can't wait


Replace the favicon.ico in your public folder with yours, that should get you going.


Here is all you need:

new HtmlWebpackPlugin({
    favicon: "./src/favicon.gif"
})

That is definitely after adding "favicon.gif" to the folder "src".

This will transfer the icon to your build folder and include it in your tag like this <link rel="shortcut icon" href="favicon.gif">. This is safer than just importing with copyWebpackPLugin


Adding your favicon simply into to the public folder should do. Make sure the favicon is named as favicon.ico.


For future googlers: You can also use copy-webpack-plugin and add this to webpack's production config:

plugins: [
  new CopyWebpackPlugin({ 
    patterns: [ 
     // relative path is from src
     { from: './static/favicon.ico' }, // <- your path to favicon
    ]
 })
]

I use favicons-webpack-plugin

const FaviconsWebpackPlugin = require("favicons-webpack-plugin");

module.exports={
plugins:[
    new FaviconsWebpackPlugin("./public/favicon.ico"),
//public is in the root folder in this app. 

]
}

In my case -- I am running Visual Studio (Professional 2017) in debug mode with webpack 2.4.1 -- it was necessary to put the favicon.ico into the root directory of the project, right where the folder src is rather than in a folder public, even though according to https://create-react-app.dev/docs/using-the-public-folder the latter should be the official location.


This worked for me:

Add this in index.html (inside src folder along with favicon.ico)

**<link rel="icon" href="/src/favicon.ico" type="image/x-icon" />**

webpack.config.js is like:

 plugins: [new HtmlWebpackPlugin({`enter code here`
        template: './src/index.html'
    })],

Browsers look for your favicon in /favicon.ico, so that's where it needs to be. You can double check if you've positioned it in the correct place by navigating to [address:port]/favicon.ico and seeing if your icon appears.

In dev mode, you are using historyApiFallback, so will need to configure webpack to explicitly return your icon for that route:

historyApiFallback: {
    index: '[path/to/index]',
    rewrites: [
        // shows favicon
        { from: /favicon.ico/, to: '[path/to/favicon]' }
    ]
}

In your server.js file, try explicitly rewriting the url:

app.configure(function() {
    app.use('/favicon.ico', express.static(__dirname + '[route/to/favicon]'));
});

(or however your setup prefers to rewrite urls)

I suggest generating a true .ico file rather than using a .png, since I've found that to be more reliable across browsers.


It's the same as adding any other external script or stylesheet. All you have to do is focus on giving the correct path and rel and type.

Note: When my favicon image was in the assets folder, it was not displaying the favicon. So I copied the image to the same folder as of my index.html and it worked perfectly as it should.

<head>
    <link rel="shortcut icon" type="image/png/ico" href="/favicon.png" />
    <title>SITE NAME</title>
</head>

It worked for me. Hope it works for you too.


Another alternative is

npm install react-favicon

And in your application you would just do:

   import Favicon from 'react-favicon';
   //other codes

    ReactDOM.render(
        <div>
            <Favicon url="/path/to/favicon.ico"/>
            // do other stuff here
        </div>
        , document.querySelector('.react'));

Use the file-loader for that:

{
    test: /\.(svg|png|gif|jpg|ico)$/,
    include: path.resolve(__dirname, path),
    use: {
        loader: 'file-loader',
        options: {
            context: 'src/assets',
            name: 'root[path][name].[ext]'
        }
    }
}

Here is how I did.

public/index.html

I have added the generated favicon links.

...
<link rel="icon" type="image/png" sizes="32x32" href="%PUBLIC_URL%/path/to/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="%PUBLIC_URL%/path/to/favicon-16x16.png" />
<link rel="shortcut icon" href="%PUBLIC_URL%/path/to/favicon.ico" type="image/png/ico" />

webpack.config.js

new HTMLWebpackPlugin({
   template: '/path/to/index.html',
   favicon: '/path/to/favicon.ico',
})

Note

I use historyApiFallback in dev mode, but I didn't need to have any extra setup to get the favicon work nor on the server side.


Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to node.js

Hide Signs that Meteor.js was Used Querying date field in MongoDB with Mongoose SyntaxError: Cannot use import statement outside a module Server Discovery And Monitoring engine is deprecated How to fix ReferenceError: primordials is not defined in node UnhandledPromiseRejectionWarning: This error originated either by throwing inside of an async function without a catch block dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.62.dylib error running php after installing node with brew on Mac internal/modules/cjs/loader.js:582 throw err DeprecationWarning: Buffer() is deprecated due to security and usability issues when I move my script to another server Please run `npm cache clean`

Examples related to reactjs

Error: Node Sass version 5.0.0 is incompatible with ^4.0.0 TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type undefined raised when starting react app Template not provided using create-react-app How to resolve the error on 'react-native start' Element implicitly has an 'any' type because expression of type 'string' can't be used to index Invalid hook call. Hooks can only be called inside of the body of a function component How to style components using makeStyles and still have lifecycle methods in Material UI? React Hook "useState" is called in function "app" which is neither a React function component or a custom React Hook function How to fix missing dependency warning when using useEffect React Hook? Unable to load script.Make sure you are either running a Metro server or that your bundle 'index.android.bundle' is packaged correctly for release

Examples related to webpack

Error: Node Sass version 5.0.0 is incompatible with ^4.0.0 Support for the experimental syntax 'classProperties' isn't currently enabled npx command not found where is create-react-app webpack config and files? How can I go back/route-back on vue-router? webpack: Module not found: Error: Can't resolve (with relative path) Refused to load the font 'data:font/woff.....'it violates the following Content Security Policy directive: "default-src 'self'". Note that 'font-src' The create-react-app imports restriction outside of src directory How to import image (.svg, .png ) in a React Component How to include css files in Vue 2

Examples related to favicon

Add Favicon with React and Webpack What is the best practice for creating a favicon on a web site? HTML 5 Favicon - Support? How can I get a favicon to show up in my django app? How to set-up a favicon? Favicon not showing up in Google Chrome Add image in title bar How to set custom favicon in Express? Why does my favicon not show up? Correct MIME Type for favicon.ico?