Vue router and webpack - history mode config localhost

Basically, I’m using Vue cli with webpack template and I need to use history mode in vue router, but i’m using params for a route.

I read this doc: https://router.vuejs.org/en/essentials/history-mode.html and I look this thread too: Problems with vue router (history mode) in development server Vue.js - “Cannot GET /config”

So I change webpack.dev.conf.js from:

historyApiFallback: {
      rewrites: [
        { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
      ],
    }

to

historyApiFallback: true

Now I get a blank page when tried to access a page with params. Any clue?

The Webpack template is preconfigured to work with history mode out of the box, you should not have to change anything (I maintain this template).

That’s not a problem, it’s a normal use case.

Wh did you change the config? Did you experience any problems before you did so? If so please explain.

Yes, before when I open a page I got “Cannot GET /partner/61309”, similar to this thread: Npm run dev “Cannot GET /config” - vue router history mode

Then, if I change to true, I get a blank page.

Please don’T mess with the historyAPIFallback config.

This is all preconfigured to just work

Please share your router config as well as the content of /config/index.js

I kept original code, but its a issue already expose on stackoverflow and even this forum. The only answers was about historyAPIFallback.

My only changes in config/index.js was to modify absolute to relative paths (if its not, the project wouldn’t work in a sub-folder server)

'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.

const path = require('path')

module.exports = {
  dev: {

    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '',
    proxyTable: {},

    // Various Dev Server settings
    host: 'localhost', // can be overwritten by process.env.HOST
    port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
    autoOpenBrowser: false,
    errorOverlay: true,
    notifyOnErrors: true,
    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-

    
    /**
     * Source Maps
     */

    // https://webpack.js.org/configuration/devtool/#development
    devtool: 'cheap-module-eval-source-map',

    // If you have problems debugging vue-files in devtools,
    // set this to false - it *may* help
    // https://vue-loader.vuejs.org/en/options.html#cachebusting
    cacheBusting: true,

    cssSourceMap: true
  },

  build: {
    // Template for index.html
    index: path.resolve(__dirname, '../dist/index.html'),

    // Paths
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: '',

    /**
     * Source Maps
     */

    productionSourceMap: true,
    // https://webpack.js.org/configuration/devtool/#production
    devtool: '#source-map',

    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: false,
    productionGzipExtensions: ['js', 'css'],

    // Run the build command with an extra argument to
    // View the bundle analyzer report after build finishes:
    // `npm run build --report`
    // Set to `true` or `false` to always turn it on or off
    bundleAnalyzerReport: process.env.npm_config_report
  }
}

It looks that removing absolute path references in config/index.js file (as default setup) resolves “this” problem, but then how can I handle a vue cli project with webpack to use as relative folder? I need to put it on a sub-folder.

Okay, we are getting closer, now we are finally talking about your real requriements and causes of the issue.

A few points:

  • history mode can’t really work without absolute paths. Releative paths to aset files will break when you visit a subroute directly. That’s not something you will be able to work around.
  • If you want to serve from a subfolder, you have to let the router know about that by setting the base option.
  • you also have set write subfolder as the assetsPublicPath in the config (for both build and dev, unless you make the router’s base switch according to environment).

Then you build your app and put the content of the dist folder into the subfolder you serve from.

Thanks. I’ll try it and return feedback.

Is working in development, but not in production when I try to go "partners/partner/:id. Before it was working.

import Vue from 'vue'
import Router from 'vue-router'
import Partners from '@/components/Partners'
import PartnerDetail from '@/components/PartnerDetail'

Vue.use(Router)

export default new Router({
  mode: 'history',
  base: '/partners/',
  routes: [
    {
      path: '/',
      name: 'Partners',
      component: Partners
    },
    {
      path: '/partner/:id',
      name: 'PartnerDetail',
      component: PartnerDetail
    }
  ]
})

My config/index.js:

'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.

const path = require('path')

module.exports = {
  dev: {

    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/partners/',
    proxyTable: {},

    // Various Dev Server settings
    host: 'localhost', // can be overwritten by process.env.HOST
    port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
    autoOpenBrowser: false,
    errorOverlay: true,
    notifyOnErrors: true,
    poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-

    
    /**
     * Source Maps
     */

    // https://webpack.js.org/configuration/devtool/#development
    devtool: 'cheap-module-eval-source-map',

    // If you have problems debugging vue-files in devtools,
    // set this to false - it *may* help
    // https://vue-loader.vuejs.org/en/options.html#cachebusting
    cacheBusting: true,

    cssSourceMap: true
  },

  build: {
    // Template for index.html
    index: path.resolve(__dirname, '../dist/index.html'),

    // Paths
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: '/partners/',

    /**
     * Source Maps
     */

    productionSourceMap: true,
    // https://webpack.js.org/configuration/devtool/#production
    devtool: '#source-map',

    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: false,
    productionGzipExtensions: ['js', 'css'],

    // Run the build command with an extra argument to
    // View the bundle analyzer report after build finishes:
    // `npm run build --report`
    // Set to `true` or `false` to always turn it on or off
    bundleAnalyzerReport: process.env.npm_config_report
  }
}

I’m trying to figure out if its a server problem, but it doesn’t work in a prod localhost. It can be?

Again, please always be precise. What does “it doesn’t work” mean?

Also, did you configure your production server for history mode, as explained in the vue documentation?

I assume you did not, you didn’t say so at least.

Sorry, when I say it doesn’t work is a “cannot get” issue, probably it is just a server config, but I need to wait server admin answer. But I left a understandable question, I think: I set up a localhost (with gulp/browser-sync to be specific) just to run the “dist” page (localhost:3000/partners/partner/:id, i put dist folder inside “partners” to simulate final environment). My question: a localhost need a configuration as a server or it can be other issue?

(Sorry for this noob question, I’m not used to deal with this subject)

The “localhost” server would also need the special config to work with history mode, yes.

1 Like