Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

  • Navigating to https://localhost:9000 redirects me to https://wordpress.local with a 301. I've disabled canonical redirects with remove_filter('template_redirect', 'redirect_canonical'); but doesn't help.
  • Navigating to https://localhost:9000/404 presents me a 404 page that is provided by my theme. No redirect happens.
  • Navigating to https://localhost:9000/existing-page/ redirects me to https://localhost/existing-page/ with a 301.

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?

like image 919
Christian Avatar asked Apr 13 '17 08:04

Christian


2 Answers

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"
},
like image 100
Christian Avatar answered Nov 15 '22 07:11

Christian


It's probably the redirect settings of your Wordpress site. If you access your site through http://localhost:9000 then that should be the domain Wordpress is aware of.

Set it in Wordpress' admin or directly in the database:

UPDATE `wp_options` SET `option_value` = "http://localhost:9000" WHERE `option_name` = "siteurl" OR `option_name` = "home";
like image 41
Tom Avatar answered Nov 15 '22 07:11

Tom