What I'm trying to achieve is to add Vue 3 app into an existing Rails application. So my app would be a typical Rails app until the route /spa/*
is loaded. In that case Rails' controller would serve a layout that dependes on Webpack served JS...
First of all I added the route /spa/
to my routes.rb
in order to always resolve it into a controller that serves the correct layout that uses javascript_pack_tag
Then, I've managed to install and setup Webpacker in my Rails 5.2
rails app and it seems it's working correctly since I've built a simple app with a Vue router and a few components that are rendered correctly when the link is clicked. Well, almost...
The problem is in that I'm serving the Vue app under the path /spa/
instead of the root /
. When I load the /spa/
URL my header component (that holds links) is shown, but the initial component (The one in the Vue router) is not rendered until I click on the Vue link. The component gets rendered, but the URL changes from /spa/
to /q1
. Obviously, if we reload the browser that route is not "controlled" by Vue, but by Rails
What I'd like to achieve is to tell the Webpack(er) and Vue to add /spa/
before any Vue router link.
<nav id="nav">
<router-link to="/">Question 1</router-link>
<router-link to="/q2">Question 2</router-link>
</nav>
I know I could hard code the /spa
to every link I'm using, but that feels so dirty :D
My Vue Router:
import { createWebHistory, createRouter } from "vue-router";
import Question1 from "@/vue/views/Question1.vue";
import Question2 from "@/vue/views/Question2.vue";
// import About from "@/views/About.vue";
const routes = [
{
path: "q1",
name: "Question1",
component: Question1,
},
{
path: "q3",
name: "Question2",
component: Question2,
},
{
path: "",
redirect: { name: 'Question1' }
}
];
const router = createRouter({
history: createWebHistory(),
// publicPath: '/spa',
base: '/spa/',
routes,
});
export default router;
According to the Vue 3 docs this should be solved quite easily by adding the base
parameter to the Router config, but it's not working :/ and neither is the publicPath
I also found somewhere that with Webpack and Vue this could be solved by adding the path to the vue.config.js
, but using the Webpacker gem I'm not sure how to do it.
The question is:
How do I make my Vue app that gets served when the route /spa/
is called behave as if /spa/
didn't exist?
FINAL EDIT
Jump to @Excalibaard's answer :)
In my case the problem was that I was using Vue router v4 that has a different syntax from the one that you normally see when searching for the Router docs.
In the router v3 the base:
is an attribute of an object that is passed to the createRouter()
function
In v4 base
is a parameter that is given to a createWebHistory("the-base-value")
So, the solution in my case would be
const router = createRouter({
mode:history,
history: createWebHistory( '/spa/' ),
routes,
});
question from:
https://stackoverflow.com/questions/65892560/serve-vue-js-app-from-a-subpath-in-rails-5-with-webpacker