'URIError: Failed to decode param '/%PUBLIC_URL%/favicon.ico'

I am new to webpack and I got the babel loader and css loader to work and project compiles successfully but when I try to access via browser I get the below error. It looks as if PUBLIC_URL is not recognized. I believe I don't know how to configure this.

I appreciate your valuable comments.

Thanks

ℹ 「wdm」: Compiled successfully. URIError: Failed to decode param 
'/%PUBLIC_URL%/favicon.ico' at decodeURIComponent (<anonymous>) at 
decode_param (/home/mike/finance- 
grapher/node_modules/express/lib/router/layer.js:172:12) at Layer.match 
(/home/mike/finance- 
grapher/node_modules/express/lib/router/layer.js:123:27) at matchLayer 
(/home/mike/finance- 
grapher/node_modules/express/lib/router/index.js:574:18) at next 
(/home/mike/finance- 
grapher/node_modules/express/lib/router/index.js:220:15) at expressInit 
(/home/mike/finance- 
grapher/node_modules/express/lib/middleware/init.js:40:5) at Layer.handle 
[as handle_request] (/home/mike/finance- 
grapher/node_modules/express/lib/router/layer.js:95:5) at trim_prefix 
(/home/mike/finance- 
grapher/node_modules/express/lib/router/index.js:317:13) at 
/home/mike/finance-grapher/node_modules/express/lib/router/index.js:284:7 
at Function.process_params (/home/mike/finance- 
grapher/node_modules/express/lib/router/index.js:335:12)

Webpack.config.js

.babelrc

package.json

project folder structure



Solution 1:[1]

Quick fix

What if you were to replace %PUBLIC_URL% with the actual path. I think that Babel is having issues transpiling the %. Try replacing %PUBLIC_URL%/favicon.ico with /public/favicon.ico and the issue is resolved.

Better fix

Add a new rule to your webpack.config.js.

//...
{
  test: /\.(png|svg|jpg|jpeg|gif|ico)$/,
  exclude: /node_modules/,
  use: ['file-loader?name=[name].[ext]'] // ?name=[name].[ext] is only necessary to preserve the original file name
}
//...

Then have the .ico resource copied to the dist directory by adding an import in your App.js. import '../public/favicon.ico';

In your index.html; <link rel="shortcut icon" href="favicon.ico"> to make use of your icon. No longer need to provide a path since it will be copied to the dist directory

OR:

In addition to the rule added to the webpack.config.js mentioned above, adding plugins to the webpack config may be a better way to go depending on your setup.

For me this looks like adding the npm package html-webpack-plugin to the project. Then requiring it in the webpack config; const HtmlWebpackPlugin = require('html-webpack-plugin');. Then adding plugins to the module.exports.

//...
plugins: [
  new HtmlWebpackPlugin({
    template: './public/index.html',
    filename: './index.html',
    favicon: './public/favicon.ico'
  })
]
//...

Going this route and doing the work in the webpack config means the line added to the App.js to import the favicon.ico will no longer be necessary.


EDIT: As mentioned by @Tolumide

Don't forget to configure the webpack.config appropriately per environment.

Solution 2:[2]

I had the same issue and fixed it with the following:

Inside webpack.config.js in the plugins array, add HtmlWebpackPlugin and InterpolateHtmlPlugin

  new HtmlWebpackPlugin(
        Object.assign(
          {},
          {
            inject: true,
            template: paths.appHtml,
          },
          isEnvProduction
            ? {
                minify: {
                  removeComments: true,
                  collapseWhitespace: true,
                  removeRedundantAttributes: true,
                  useShortDoctype: true,
                  removeEmptyAttributes: true,
                  removeStyleLinkTypeAttributes: true,
                  keepClosingSlash: true,
                  minifyJS: true,
                  minifyCSS: true,
                  minifyURLs: true,
                },
              }
            : undefined
        )
      ),

      new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw)

This is the documentation of InterpolateHtmlPlugin

Makes some environment variables available in index.html.
The public URL is available as %PUBLIC_URL% in index.html, e.g.:
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
In production, it will be an empty string unless you specify "homepage"
in `package.json`, in which case it will be the pathname of that URL.
In development, this will be an empty string.

Solution 3:[3]

Problem fixed step 1) remove %PUBLIC_URL% with the actual path. %PUBLIC_URL%/favicon.ico with favicon.ico Before <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> After <link rel="icon" href="favicon.ico" />

step 2) add this rule to the webpack.config.js

plugins: [new HtmlWebpackPlugin({ template: path.resolve(__dirname, "public", "index.html"),
    favicon: "./public/favicon.ico",
    filename: "index.html",
    manifest: "./public/manifest.json",
  })]

step 3) add svg support in webpack(important) install svg-url-loader package

 {
        test: /\.svg$/,
        use: [
          {
            loader: 'svg-url-loader',
            options: {
              limit: 10000,
            },
          },
        ],
     }

Solution 4:[4]

<link href="<%= htmlWebpackPlugin.options.favicon %>" rel="shortcut icon">

and

new HtmlWebpackPlugin({
   favicon: "image/favicon.ico",
})

and

{
  test: /\.(jpe?g|gif|png|ico)$/,
  use: ['file-loader?name=[name].[ext]']
},

Solution 5:[5]

Solution

  1. npm install interpolate-html-plugin --save-dev
  2. Add to list of plugins in webpack config

new InterpolateHtmlPlugin({PUBLIC_URL: 'static })

Solution 6:[6]

I was getting this error from create-react-app when I was serving the page from express server. It was because I was serving static pages from public folder instead of build folder.

Not working:

app.use('/', express.static(path.join(__dirname, '../public')));

Working

app.use('/', express.static(path.join(__dirname, '../build')));

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 lele
Solution 3 Dharman
Solution 4 Vlad
Solution 5 Isha
Solution 6 Varun Kumar