Webpack-dev-server: historyApiFallback doesn't work, for scripts, if you're nested multiple path sections deep

Created on 17 Jul 2015  路  10Comments  路  Source: webpack/webpack-dev-server

I'm using historyApiFallback so that my react application can use the newer client-side routing / HTML 5 history. I've set historyApiFallback to true. This works when the client-side route is something like /users or /home, etc. This does not seem to work if the client-side route is something like /users/1, though. It tries to look for scripts within my HTML file relative to /users. Even if my HTML script is like ...

<script type="text/javascript" src="./static/app.js"></script>

it looks for that at /users/static/app.js.

Most helpful comment

Use:
devServer: { historyApiFallback: { index: '/your-public-path/' } }

All 10 comments

Actually, if I change ./static/app.js to just /static/app.js it works. Not sure which form is correct. I've been using that period-prefixed form for years. D:

@ryancole I'm having the same problem, but changing the HTML script tag to match your example doesn't seem to solve it. Any way you could post your dev server config?

Sure. My repository is here. A paste of the webpack config is ...

'use strict';

var path = require('path');
var webpack = require('webpack');

module.exports = {
  entry: [
    'webpack-dev-server/client?http://localhost:8081',
    'webpack/hot/only-dev-server',
    path.resolve(__dirname, 'src', 'App.js')
  ],
  plugins: [
    new webpack.HotModuleReplacementPlugin,
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
    })
  ],
  output: {
    path: process.env.NODE_ENV === 'production' ?
          path.resolve(__dirname, 'build', 'release', 'static') :
          path.resolve(__dirname, 'build', 'debug', 'static'),
    filename: 'app.js',
    publicPath: '/static/'
  },
  resolve: {
    alias: {
      'bootstrap': 'bootstrap/dist'
    }
  },
  devtool: 'source-map',
  devServer: {
    hot: true,
    port: 8081,
    colors: true,
    publicPath: '/static/',
    historyApiFallback: true
  },
  module: {
    preLoaders: [
      {
        test: /\.js$/,
        loader: "eslint-loader",
        include: path.resolve(__dirname, 'src')
      }
    ],
    loaders: [
      {
        test: /\.js$/,
        loaders: [
          'react-hot',
          'babel'
        ],
        include: path.resolve(__dirname, 'src')
      },
      {
        test: /\.json$/,
        loader: 'json',
        exclude: /node_modules/
      },
      {
        test: /\.css/,
        loaders: [
          'style',
          'css'
        ]
      },
      {
        test: /\.woff2?$/,
        loader: "url-loader?limit=10000&mimetype=application/font-woff"
      },
      {
        test: /(\.ttf|\.eot|\.svg)$/,
        loader: "file-loader"
      }
    ]
  }
};

@ryancole perfect, thanks!

I'm having this issue as well.

When my app is deployed to production, its basename will be "/eyeglass". Thus, I've told webpack to generate with a public path of "/eyeglass". In my single index.html file, all my resources are homed at "/eyeglass", e.g. "/eyeglass/styles.css", "/eyeglass/app.js" and so on.

Locally, I'm starting the webpack-dev-server like this: webpack-dev-server --content-base build/ -d --progress --history-api-fallback

If I navigate to "localhost:8080/eyeglass" my index.html is served up as expected.

If I navigate directly to a deep URL, like "localhost:8080/eyeglass/reviews" the webpack-dev-server returns a 404.

Any ideas?

Here's the main snippet of my config:

var config = {
  target: 'web',
  resolve: {
    extensions: ['', '.jsx', '.scss', '.js', '.json']
  },
  module: {
    loaders: [{
      test: /index\.html$/,
      loader: 'file?name=[path][name].[ext]&context=./src'
    }, {
      test: /\.json$/,
      loader: 'json'
    }, {
      test: /\.js$/,
      exclude: /node_modules/,
      loader: 'babel',
      query: {
        presets: ['react', 'es2015'],
        plugins: ['transform-es2015-spread', 'transform-object-rest-spread', 'transform-class-properties']
      }
    }, {
      test: /\.jpe?g$|\.gif$|\.png$/,
      loader: 'url!image'
    }, {
      test: /\.css$/,
      loader: ExtractTextPlugin.extract('style', 'css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]')
    }, {
      test: /\.scss$/,
      loader: ExtractTextPlugin.extract('style', 'css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!sass')
    }],
  },
  entry: {
    app: './src/index.js',
    vendor: ['react', 'react-dom', 'react-redux', 'redux', 'redux-devtools']
  },
  output: {
    path: path.resolve('./dist'),
    publicPath: '/eyeglass',
    filename: 'app.js',
    sourceMapFilename: '[file].map'
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js'),
    new ExtractTextPlugin('styles.css'),
    new webpack.DefinePlugin(definitions)
  ]
};

module.exports = config;

+1

@manekinekko #518 doesnt't fix this issue.

Use:
devServer: { historyApiFallback: { index: '/your-public-path/' } }

Setting the base tag with '/' as href in your index.html fixes it.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

StephanBijzitter picture StephanBijzitter  路  3Comments

mischkl picture mischkl  路  3Comments

adiachenko picture adiachenko  路  3Comments

subblue picture subblue  路  3Comments

antoinerousseau picture antoinerousseau  路  3Comments