Vue Router adds # (hash) after calling router.push() in "history" mode - vue.js

On a specific UI action I'm calling:
router.push({ name: router.history.current.name, params: { league: league } })
I just want to add "/:league" param at the end of the route. I have a separate route for it:
const router = new VueRouter({
mode: 'history',
routes: [
{ path: '/', component: Home, name: 'home' },
{ path: '/:league', component: Home, props: true, name: 'home/league' },
]
})
For example if the user is at / and he selects a "league" from a menu, I want the url to change to /leagueName.
It works, but it appends # at the end of the url and it ends up being /leagueName#. Is there a way to remove the hash? I'm already in "history" mode.

I found several bugs:
Check how your router is connected and configured:
const routes = [
{ path: '/', name: 'Home', component: Home },
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
You need to write $router, when you call a push.
You can't write a name like router.history.current.name, because you will go to the same page. So state explicitly: home/league.
Better not use one component to output different routes, this is not very good. But you can use child routes.

Instead of creating a separate route that points to the same component, use an optional parameter on one route:
export default new VueRouter({
mode: "history",
routes: [
{
path: "/:league?", // `?` makes `league` OPTIONAL
component: Home,
props: true,
name: "home"
}
]
});
And if you need to use $router.push() to change only the parameter value, you could omit the name or path:
<button #click="$router.push({ params: { league: 'myLeague' } })">
Go to My League
</button>
Note if the UI is intended to be a link, it might be best to use router-link, which avoids the Avoided redundant navigation to current location console warning:
<router-link :to="{ params: { league: 'myLeague' } }">Go to My League</router-link>
demo

Related

Set page title dependent on Vue router params

I'm not sure if this is possible, but here goes:
I'm trying to make it so the page title (the meta tag) displays the username of the profile you're currently on. My code is as follows:
export default new Router({
mode: "history",
base: process.env.BASE_URL,
routes: [
{
path: "/profile/:userId/",
name: "profile",
component: Profile,
meta: {
title: "Profile - ((USERID HERE))", // <-- Find how to insert :userId into page title
},
},
Any advice on how to accomplish this, or if it's even possible to have dynamic page titles using vue router? Thanks.
you can use router props as function,
so instead of passing a prop of userId, pass a prop of title like so:
routes: [
{
path: "/profile/:userId",
name: "profile",
component: Profile,
props: route => ({ title: `Profile ${route.params.userId}` })
},
]
you can read more about this in vue docs
You would need to set the title on each router entry
const router = new Router({
mode: "history",
base: process.env.BASE_URL,
routes: [
{
path: "/profile/:userId/",
name: "profile",
component: Profile,
meta: {
title: "Profile - ((USERID HERE))", // <-- Find how to insert :userId into page title
},
},
//Other properties
})
router.beforeEach((to, from, next) => {
// You have access to the route here so you could dynamically get the variable? to.params? (Sorry for editing this post as didn't see the full question!)
document.title = to.meta.title ? to.meta.title : "Some Default Title"
// Edit 2 it seems params contains the thing you need so you could detect if to.meta.title is a thing and dynamically change it `Profile - (${to.params.userId})`
next() // You must call next!
})
export default router

nuxt router.js rewrites after running npm run dev in vuejs app

i' m in a project (has been coded by someone else) , it has router.js file that include all app's routs , and created in a function , code below
export function createRouter() {
return new Router({
mode: 'history',
base: decodeURI('/'),
linkActiveClass: 'nuxt-link-active',
linkExactActiveClass: 'nuxt-link-exact-active',
scrollBehavior,
routes: [{
path: "/login",
component: _32e99e0f,
name: "login"
}, {
path: "/orders",
component: _5838bb72,
name: "orders"
}, {
path: "/profile",
component: _1a272ccf,
name: "profile"
}, {
path: "/orders/new",
component: _2c62ddc3,
name: "orders-new"
}, {
path: "/orders/new/:step",
component: _91e13fc8,
name: "orders-new-step"
}, {
path: "/orders/:order",
component: _14e0655f,
name: "orders-order"
}, {
path: "/",
component: _6941faf8,
name: "index"
}],
fallback: false
})
}
this function has been import and called in a function named createApp in index.js file, code below
async function createApp(ssrContext) {
const router = await createRouter(ssrContext)
const store = createStore(ssrContext)
// Add this.$router into store actions/mutations
store.$router = router
.
.
.
}
it seems stores in an array , and used globally that seems ok ,
the issue comes when i change one of routes and make a new one , like
export function createRouter() {
return new Router({
mode: 'history',
base: decodeURI('/'),
linkActiveClass: 'nuxt-link-active',
linkExactActiveClass: 'nuxt-link-exact-active',
scrollBehavior,
routes: [{
path: "/new-route",
component: _newname,
name: "newRoute"
},
.
.
.
when i use npm run dev or npm run generate, the function and its data has been overwrited and came back to the original code .
can anyone please make me a sense of what is happening hear , i'm so new in vue.js ;) and need some kindness .

VueJS add external site to router history

I am building an app using Vue Router that uses an "external" site for login credentials. It essentially looks like this:
Home.Vue
<template>
</template>
<script>
export default {
name: "Home",
data() {
return {
}
},
created() {
window.location = 'https://third_party_site.com?nextpage=http://my_site.com/#/entry'
}
}
</script>
<style scoped>
</style>
This third_party_site.com handles auth and sends a JWT back as a query string in the resulting URL. When I try to use a navigation guard (as shown below) to get the query string, Vue router only looks in the router's history.
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from '#/components/Home'
import Entry from '#/components/Entry'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'Home',
component: Home,
},
{
path: '/entry',
name: 'Entry',
component: Entry,
beforeEnter: (to, from, next) => {
console.log('to',to)
console.log('from',from)
console.log('next',next)
next()
},
meta: {
title: 'Entry'
}
},
]
})
The console prints the expected "to" location but the "from" location is the base path, "/", and there are no query parameters. How do I go about getting the "external" route so I can access the query parameters? The resulting console.log of "from" is below.
from
{name: null, meta: {…}, path: "/", hash: "", query: {…}, …}
fullPath: "/"
hash: ""
matched: []
meta: {}
name: null
params: {}
path: "/"
query: {}
__proto__: Object
Before asking, the app, in its current state, has to be built this way and I do not have access to the external site.
Wild shot in the dark here but the # in your nextpage query parameter is probably messing with the remote site.
What it will see is
QUERY => nextpage=http://my_site.com/
FRAGMENT => #/entry
so it will redirect back to http://my_site.com/ because it probably ignores any fragment.
You should encode the value correctly, eg
window.location = 'https://third_party_site.com/?nextpage=' +
encodeURIComponent('http://my_site.com/#/entry')
which will produce nextpage=http%3A%2F%2Fmy_site.com%2F%23%2Fentry

Cannot read query params becouse vue.js is adding #/ to the end of url

I have a one page app in vueJS:
let router = new VueRouter({
routes: [
{ path: '/', component: Dis13HomeComponent },
{ path: '**', component: Dis13HomeComponent }
]
});
In main component in mounted() im getting the url param like this:
this.$route.query.token;
But if I open http://www.myapp.com/app.html?token=s56ds6d5d56f6ef6e it does not read the token parameter, becouse vue is adding #/ to the end of url so it looks like http://www.myapp.com/app.html?token=s56ds6d5d56f6ef6e#/
If I open this format of url: http://www.myapp.com/app.html#/?token=s56ds6d5d56f6ef6e then it works, but this path is forbidden on server.
How could I read the token parameter?
Make your router to work with history mode and you will not have the '#' anymore.
const router = new VueRouter({
mode: 'history', // <------------- HERE
routes: [
{ path: '/', component: Dis13HomeComponent },
{ path: '**', component: Dis13HomeComponent }
]
});

VueRouter omitting the forward slash before the # in non-history mode

i'm trying to use VueRouter 2.2.1 in my Laravel application and for some reason my URL's (although working) show the # symbol in a weird way
http://myapp.dev/admin#/
Instead of
http://myapp.dev/admin/#/
As i would normally expect...
This is my VueRouter configuration
const Router = new VueRouter({
routes: [
{
path: '/',
component: App,
children: [
{
path: 'dashboard',
name: 'dashboard',
component: Dashboard
}
]
}
]
});
And on the PHP side of things i'm just defining a catch all route for the /admin section of the Application
// Catch-all Route, sends GET requests to VueRouter //
Route::get('{all?}', function() {
return view('index');
})->where(['all' => '(.*)'])->name('catchall');
Like this, is there anything i'm doing wrong? It is working but it just kinda bugs me that the # just floats there.
You have to enable history mode, as stated here, I dont see that in your vue-router config.
const Router = new VueRouter({
mode: 'history',
routes: [
{
path: '/',
component: App,
children: [
{
path: 'dashboard',
name: 'dashboard',
component: Dashboard
}
]
}
]
});
You have to do it on server side, just redirect the route to one ended with '/'
As in laravel:
Route::get('{all?}', function() {
return view('index');
})->where(['all' => '^/admin\/$'])->name('catchall');
now just visit /admin/#/