diff --git a/config/paths.js b/config/paths.js
index 7645917fbc95504483c75679eee42bd417624f93..e6f2ff6cb3a669d5ebe8a6f0a78e352d899ff70c 100644
--- a/config/paths.js
+++ b/config/paths.js
@@ -36,7 +36,6 @@ if (isInCreateReactAppSource) {
   module.exports = {
     appBuild: resolveOwn('../build'),
     appHtml: resolveOwn('../template/index.html'),
-    appFavicon: resolveOwn('../template/favicon.ico'),
     appPackageJson: resolveOwn('../package.json'),
     appSrc: resolveOwn('../template/src'),
     appNodeModules: resolveOwn('../node_modules'),
@@ -47,7 +46,6 @@ if (isInCreateReactAppSource) {
   module.exports = {
     appBuild: resolveApp('build'),
     appHtml: resolveApp('index.html'),
-    appFavicon: resolveApp('favicon.ico'),
     appPackageJson: resolveApp('package.json'),
     appSrc: resolveApp('src'),
     appNodeModules: resolveApp('node_modules'),
@@ -59,7 +57,6 @@ if (isInCreateReactAppSource) {
   module.exports = {
     appBuild: resolveApp('build'),
     appHtml: resolveApp('index.html'),
-    appFavicon: resolveApp('favicon.ico'),
     appPackageJson: resolveApp('package.json'),
     appSrc: resolveApp('src'),
     appNodeModules: resolveApp('node_modules'),
diff --git a/config/webpack.config.dev.js b/config/webpack.config.dev.js
index ae95e0d92b85136481b636a3c7cc33b55886ba38..5e28bb7c916cb5e082422da7efa1f0c1964bf734 100644
--- a/config/webpack.config.dev.js
+++ b/config/webpack.config.dev.js
@@ -126,13 +126,23 @@ module.exports = {
       // When you `import` an asset, you get its (virtual) filename.
       // In production, they would get copied to the `build` folder.
       {
-        test: /\.(jpg|png|gif|eot|svg|ttf|woff|woff2)(\?.*)?$/,
+        test: /\.(ico|jpg|png|gif|eot|svg|ttf|woff|woff2)(\?.*)?$/,
         include: [paths.appSrc, paths.appNodeModules],
+        exclude: /\/favicon.ico$/,
         loader: 'file',
         query: {
           name: 'static/media/[name].[ext]'
         }
       },
+      // A special case for favicon.ico to place it into build root directory.
+      {
+        test: /\/favicon.ico$/,
+        include: [paths.appSrc],
+        loader: 'file',
+        query: {
+          name: 'favicon.ico?[hash:8]'
+        }
+      },
       // "url" loader works just like "file" loader but it also embeds
       // assets smaller than specified size as data URLs to avoid requests.
       {
@@ -143,6 +153,15 @@ module.exports = {
           limit: 10000,
           name: 'static/media/[name].[ext]'
         }
+      },
+      // "html" loader is used to process template page (index.html) to resolve
+      // resources linked with <link href="./relative/path"> HTML tags.
+      {
+        test: /\.html$/,
+        loader: 'html',
+        query: {
+          attrs: ['link:href'],
+        }
       }
     ]
   },
@@ -169,7 +188,6 @@ module.exports = {
     new HtmlWebpackPlugin({
       inject: true,
       template: paths.appHtml,
-      favicon: paths.appFavicon,
     }),
     // Makes some environment variables available to the JS code, for example:
     // if (process.env.NODE_ENV === 'development') { ... }. See `env.js`.
diff --git a/config/webpack.config.prod.js b/config/webpack.config.prod.js
index 66ca7a8cec189a1fdb0c288d8213b5b9fa70179e..ffeb75a9488b41886ca43f2ea6177edb6dd2a66e 100644
--- a/config/webpack.config.prod.js
+++ b/config/webpack.config.prod.js
@@ -126,23 +126,33 @@ module.exports = {
         loader: ExtractTextPlugin.extract('style', 'css?-autoprefixer!postcss')
         // Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
       },
+      // JSON is not enabled by default in Webpack but both Node and Browserify
+      // allow it implicitly so we also enable it.
       {
-        // JSON is not enabled by default in Webpack but both Node and Browserify
-        // allow it implicitly so we also enable it.
         test: /\.json$/,
         include: [paths.appSrc, paths.appNodeModules],
         loader: 'json'
       },
+      // "file" loader makes sure those assets end up in the `build` folder.
+      // When you `import` an asset, you get its filename.
       {
-        // "file" loader makes sure those assets end up in the `build` folder.
-        // When you `import` an asset, you get its filename.
-        test: /\.(jpg|png|gif|eot|svg|ttf|woff|woff2)(\?.*)?$/,
+        test: /\.(ico|jpg|png|gif|eot|svg|ttf|woff|woff2)(\?.*)?$/,
+        exclude: /\/favicon.ico$/,
         include: [paths.appSrc, paths.appNodeModules],
         loader: 'file',
         query: {
           name: 'static/media/[name].[hash:8].[ext]'
         }
       },
+      // A special case for favicon.ico to place it into build root directory.
+      {
+        test: /\/favicon.ico$/,
+        include: [paths.appSrc],
+        loader: 'file',
+        query: {
+          name: 'favicon.ico?[hash:8]'
+        }
+      },
       // "url" loader works just like "file" loader but it also embeds
       // assets smaller than specified size as data URLs to avoid requests.
       {
@@ -153,6 +163,15 @@ module.exports = {
           limit: 10000,
           name: 'static/media/[name].[hash:8].[ext]'
         }
+      },
+      // "html" loader is used to process template page (index.html) to resolve
+      // resources linked with <link href="./relative/path"> HTML tags.
+      {
+        test: /\.html$/,
+        loader: 'html',
+        query: {
+          attrs: ['link:href'],
+        }
       }
     ]
   },
@@ -181,7 +200,6 @@ module.exports = {
     new HtmlWebpackPlugin({
       inject: true,
       template: paths.appHtml,
-      favicon: paths.appFavicon,
       minify: {
         removeComments: true,
         collapseWhitespace: true,
diff --git a/package.json b/package.json
index 77910fcf3498df86992ecbe1365bc67278a57cf3..1b389da8005e0ba3179ca0902bba0e383f13280d 100644
--- a/package.json
+++ b/package.json
@@ -61,6 +61,7 @@
     "filesize": "3.3.0",
     "fs-extra": "0.30.0",
     "gzip-size": "3.0.0",
+    "html-loader": "0.4.3",
     "html-webpack-plugin": "2.22.0",
     "http-proxy-middleware": "0.17.0",
     "jest": "14.1.0",
diff --git a/tasks/e2e.sh b/tasks/e2e.sh
index a1566a85bdb903c8878ac9a0c04b43118dc36164..6e6c20c9420319fb05e0337b1d03e55498414d01 100755
--- a/tasks/e2e.sh
+++ b/tasks/e2e.sh
@@ -67,6 +67,7 @@ test -e build/*.html
 test -e build/static/js/*.js
 test -e build/static/css/*.css
 test -e build/static/media/*.svg
+test -e build/favicon.ico
 
 # Run tests
 npm run test
@@ -96,6 +97,7 @@ test -e build/*.html
 test -e build/static/js/*.js
 test -e build/static/css/*.css
 test -e build/static/media/*.svg
+test -e build/favicon.ico
 
 # Run tests
 npm run test
@@ -113,6 +115,7 @@ test -e build/*.html
 test -e build/static/js/*.js
 test -e build/static/css/*.css
 test -e build/static/media/*.svg
+test -e build/favicon.ico
 
 # Run tests
 npm run test
diff --git a/template/index.html b/template/index.html
index 72e10e94c6cc05d7f15f45424fa9b7ed05741fe8..f89671553ebcf7a8e800e08a35d3807bccc762b0 100644
--- a/template/index.html
+++ b/template/index.html
@@ -3,6 +3,7 @@
   <head>
     <meta charset="utf-8">
     <meta name="viewport" content="width=device-width, initial-scale=1">
+    <link rel="shortcut icon" href="./src/favicon.ico">
     <title>React App</title>
   </head>
   <body>
diff --git a/template/favicon.ico b/template/src/favicon.ico
similarity index 100%
rename from template/favicon.ico
rename to template/src/favicon.ico