wordpresshttp-redirectwebpackwebpack-dev-serverwebpack-2

WordPress redirecting to siteurl when accessed via webpack-dev-server proxy


This question has historical value, so I'm updating it a bit. It's the top result for "webpack-dev-server wordpress redirect" in Google. While the accepted solution worked for Webpack 2, it might not work anymore. If it doesn't you can refer to my wordpress-theme-base repository, which is built using Webpack 4.


First of all, this is related to Wordpress redirecting to localhost instead of virtual host when being proxied by Webpack Dev Server. I'm facing a similar problem, but the only solution didn't really do anything for me.

I'm running WordPress 4.7 inside a Vagrant development machine, and it responds to http://wordpress.local just like it should. Previously I've used Browsersync to watch my files and trigger a refresh, and this works as expected: browser-sync start --proxy 'https://wordpress.local' --files '**/dist/js/*.js, **/*.css, **/*.php'.

However, with webpack-dev-server I'm unable to replicate the behaviour. This is what should happen.

  1. Server starts in https://localhost:9000
  2. Navigating to https://localhost:9000 should present me with the same page as navigating to https://wordpress.local, without any redirections. Site works as it was https://wordpress.local, but the URL is https://localhost:9000.
  3. Changes happen, page gets reloaded.

Instead, this happens.

What on earth is going on? I've narrowed the problem to WordPress, as proxying a non-WordPress directory works as expected:

Direct, contents of $_SERVER: https://gist.github.com/k1sul1/0aff7ba905464ca7852f2ce00b459922

Proxied, contents of $_SERVER: https://gist.github.com/k1sul1/f090aa103dc3a3cb0b339269560ac19d

I've tried playing around with headers and such, without luck. Here's what my webpack.config.js looks like:

const path = require('path');
const url = 'https://wordpress.local/';
const themeDir = '/wp-content/themes/themename/';

module.exports = {
  entry: './src/js/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
    publicPath: url
  },
  devServer: {
    historyApiFallback: true,
    compress: true,
    port: 9000,
    https: url.indexOf('https') > -1 ? true : false,
    publicPath: themeDir,
    proxy: {
      '*': {
        'target': url,
        'secure': false
      },
      // '/': { // This doesn't do much. 
        // target: url,
        // secure: false
      // }
    },
  }
};

TL;DR: How do I replicate Browsersync behaviour with webpack-dev-server without WordPress going crazy?


Solution

  • I did eventually solve this. The magic lines that go into the proxy config are changeOrigin: true and autoRewrite: true. Those options go into http-proxy-middleware.

    Any changes to WordPress domain or config are unnecessary.

    const path = require('path');
    const pjson = require(path.join(__dirname, '..', 'package.json'));
    
    const isWin = /^win/.test(process.platform);
    const isMac = /^darwin/.test(process.platform);
    const isHTTPS = pjson.wptheme.proxyURL.includes('https');
    
    exports.devServer = ({ host, port } = {}) => {
      const options = {
        host: host || process.env.HOST || 'localhost', 
        port: port || process.env.PORT || 8080,
      };
      options.publicPath = (isHTTPS ? 'https' : 'http') + '://' + options.host + ':' + options.port + pjson.wptheme.publicPath;
    
      return {
        devServer: {
          watchOptions: {
            poll: isWin || isMac ? undefined : 1000,
            aggregateTimeout: 300,
          },
    
          https: isHTTPS,
          stats: 'errors-only',
          host: options.host,
          port: options.port,
          overlay: {
            errors: true,
            warnings: false,
          },
    
          open: true,
          hotOnly: true,
    
          proxy: {
            '/': {
              target: pjson.wptheme.proxyURL,
              secure: false,
              changeOrigin: true,
              autoRewrite: true,
              headers: {
                'X-ProxiedBy-Webpack': true,
              },
            },
          },
    
          publicPath: options.publicPath,
        },
      };
    };
    

    The values referenced from package.json look like this:

    "wptheme": {
      "publicPath": "/wp-content/themes/themefolder/dist/",
      "proxyURL": "https://wordpress.local"
    },