I am trying to dynamically pass in data to set the base for vue-router. Is it possible to setup a separate function elsewhere that passes in a base name variable? For example, if an editor wanted to set the base name via a CMS, I’d want a way to pass (or import) that name through.
// router/index.js
export default new VueRouter({
base: '[PASS BASE NAME HERE]',
routes: [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/contact',
name: 'Contact',
component: Contact
}
],
mode: 'history'
})
I ended up setting a variable on my index.html and importing it to the router. This can also be done by importing a variable from a module js file, but setting it on the html seems to avoid build issues. Simpler solution than I thought, thanks #lamelemon.
// index.html
var serializedModel = #Html.Raw(Model.Serialized());
// router/index.js
var baseUrl = serializedModel.BaseUrl;
export default new VueRouter({
base: baseUrl,
mode: 'history',
routes: [{...}]
})
Related
I'm working on a Vue.Js site and using the Vue-router default mode "hash". So the site URL is something like that:
www.mysite.com/#/Home
This site is already being linked by some mobile apps, and I can't change them. But I have a new requirement and I need to change the URLs to remove the hash (#) from the URL. So I changed the Vue-router mode to "history" and now my site is working without the hash. Like that:
www.mysite.com/Home
The problem is that using the history mode the URL with the hash (#) doesn't work. But for compatibility with the mobile apps that link the site with hash, I still need to make the URL with the hash works.
QUESTION:
How can I use the Vue-router history mode and also keep the URLs with hash working?
I tried the following way at the router/index.js file:
export default new Router({
mode: 'history',
routes: [
{
path: '/Home',
name: 'Home1',
component: Home
},
{
path: '/#/Home',
name: 'Home2',
component: Home
},
...
]})
Using this configuration the URL www.mysite.com/Home works, but the URL www.mysite.com/#/Home doesn't work.
I'm answering my own question based on the comment of the #Ohgodwhy and a question/answer from the vue.js forum that was answered by #nathany.
The solution is to remove the has (#) from the URLs that have the hash, and redirecting it to the URL without the hash. It can be done at the method router.beforeEach().
My router/index.js was something like that:
import Vue from 'vue'
import Router from 'vue-router'
import Home from '#/components/Home'
export default new Router({
mode: 'history',
routes: [
{
path: '/Home',
name: 'Home',
component: Home
},
],
})
Then I changed to:
import Vue from 'vue'
import Router from 'vue-router'
import Home from '#/components/Home'
var router = new Router({
mode: 'history',
routes: [
{
path: '/Home',
name: 'Home',
component: Home
},
],
})
export default router;
router.beforeEach((to, from, next) => {
// Redirect if fullPath begins with a hash (ignore hashes later in path)
if (to.fullPath.substr(0,2) === "/#") {
const path = to.fullPath.substr(2);
next(path);
return;
}
next();
});
For me I just needed to route external legacy links to current history-mode.
In App.vue mounted:
if (location.hash) {
location.replace(location.hash.replace('#', ''))
}
If you stumble across this...
The currently accepted answer works... But if you have a id link in the root path (for example, /#learn-more), the router redirects to /learn-more and would return a 404.
So, I modified the beforeEach route guard to:
router.beforeEach((to, _from, next) => {
if (to.hash.startsWith('#/')) {
const path = to.fullPath.substring(2);
next(path);
return;
}
next();
});
Why? In hash mode, links are passed as hashes
// console.log(to)
{
fullPath: "/#/contact",
path: "/",
hash: "#/contact",
...
}
...while normal id links (in history mode) give
{
fullPath: "/about#learn-more",
hash: "#learn-more",
path: "/about",
...
}
Looking at hash, the difference between a link to an id and a hash-mode link is #/
This issue has been discussed several times (1 - 2) but I still cannot get it to work. I'm transitioning our project to use vue in some parts. What I want to accomplish is:
If url starts with /v/, look into vue router and match path.
If url starts with anything other than /v/, ignore it (this view will be rendered by current framework from backend).
My router looks like:
const router = new Router({
base: '/v/',
mode: 'history',
routes: routes
});
Where routes are:
const routers = [
...
{
path: '/wholesale-catalogue/',
name: 'wholesale-catalogue',
component: () => import('./views/WholesaleCatalogue.vue')
}
...
]
The second option I tried is nesting the children routes:
const router = new Router({
mode: 'history',
routes: [
{ path: 'v', component: BaseView, children: routers }
]
});
The problem is that the router reroutes non /v/ urls into /v/ when clicked within the website, such as:
ourwebsite.com/home/ -> has some links on it, such as /about/. When you click on /about/ it actually goes to ourwebsite.com/about/ for a few seconds but then the url changes to /ourwebsite.com/v/about/. This leads to some annoyances as when you refresh the website, this url doesn't exist (on our current backend framework) so it will not render.
I'm working with my site at https://mtgranks.herokuapp.com/.
If you use the navigation options that appear when you click Sets and select the Dominaria option, the site properly navigates to https://mtgranks.herokuapp.com/DOM and loads the expected data.
The problem I am running into is if I type https://mtgranks.herokuapp.com/DOM and try to directly navigate to it through the URL, the site will return a 404.
Below is my basic Router, please let me know if you'd like to see any other areas.
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '',
name: 'home',
component: Home,
},
{
// TODO: Limit available URLs people can type in.
path: '/:set',
name: 'set',
component: Set
},
]
})
Using vue-router, it keeps throwing me back to the initial component I have routed to /
Router is initialized as such:
export default new Router({
history: true,
routes: [
{
path: '/',
name: 'BodyParent',
component: BodyParent
},
{
path: '/configuration',
name: 'Configuration',
component: Configuration
}
]
})
If I go to /configuration, it will still load the BodyParent component, but the browser URL will go to /configuration initially, then to /configuration#/ while still loading BodyParent
If I put the Configuration component to route to /, it does render it. How come?
So the problem is pretty generic - Vue router defaults to the component that is set to /
The issue was that I was using a regular href to navigate.
I should have used: <router-link to="Configuration">Config</router-link>
As par documentation of base option:
The base URL of the app. For example, if the entire single page application is served under /app/, then base should use the value "/app/".
But I have tried it like following, It does not seems to work:
const router = new VueRouter({
base: "/app/",
routes
})
Demo fiddle.
The base has a default value of '/'. Drawing analogy from how it is used to route:
<router-link to="home">Home</router-link>
or
<router-link :to="{ path: '/abc'}" replace></router-link>
I just omitted the /app and it works. The base doesn't need to be part of the router-link
EDIT
Use of base in vue-router
(For this test I had used vue-cli with the webpack template.)
I had my router configurations like so:
export default new Router({
base: '/app',
mode: 'history',
routes: [
{
path: '/',
name: 'RangeInputDemo',
component: ComponentDemo
}
]
})
Adding base as '/app' made no difference to the routing that happened throughout the project, as if the base was still set to '/'.
I tried to change the url from the server side (the url at which the project is being served).
So in dev-server.js where :
var uri = 'http://localhost:' + port
controls the url of the app, I made a slight modification to:
var uri = 'http://localhost:' + port + '/app'
This caused the application to show:
Notice the fullPath being '/' in the vue console (second image).
Just for double checking, I changed the base to '/' again.
So, the base property of the router configuration is to set the base url as set by the server, if the server serves the application at a route other than '/' then the base can be used for having the application be run from the set url.
Since the question requires the routes being moved under /app, I think having /app as the parent route would be the solution in that case, if the server isn't supposed to change the route on which it serves.
In the Vue Router 4, you set base path by history api:
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
Then each path would be prefixed with process.env.BASE_URL
Had the same problem, setting "base" didn't work - workaround is to update base url in router:
{ name: 'listings', path: baseUrl + '/listings', component: PageListings}
and refer to routes by name:
<router-link :to="{ name: 'listings' }" exact>Listings</router-link>
I created a redirect on the base path to another route.
{
name: "Default",
path: '/',
redirect: { name: 'OtherRouteName' }
}
Reference:
https://next.router.vuejs.org/guide/essentials/redirect-and-alias.html