Set page title dependent on Vue router params - vue.js

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

Related

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

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

Redirect all links containing # hash sign

After changing Vue router mode from hash to history, old links do not redirect the user to the new URL.
Some still use the old link.
const router = new Router({
mode: 'history',
routes: [
{
path: '/#/',
name: 'Home',
component: Home
},
{
path: '/',
name: 'Home',
component: Home
},
]
})
I need to redirect all existing URL links to URL without hash.
You can replace hash in beforeEach hook:
router.beforeEach((to, from, next) => {
if (to.fullPath.substr(0,2) === "/#") {
const path = to.fullPath.substr(2);
next(path);
return;
}
next();
});

Vue router beforeEach

Problem is that the name gets undefined value I do not know why.
enter image description here
router.beforeEach((to, from, next) => {
console.dir(to);
});
assuming that you have router.js file or something similar your route object would look something like this
export default new Router({
routes: [
{
path: '/login',
name: 'login', // this being the name
component: () => import(whatever component),
meta: {
// some data goes here if needed
}
},
]
})
name: 'login' would be the undefined value you are seeing or what ever name you place there for whatever route

How to use vue-router to redirect to 404 page with invalid URL parameter

I use vue-router to navigate the user pages by their user id.
And the router.js looks like as follows
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/user/:id',
name: 'user',
component: () =>
import(/* webpackChunkName: "user" */ './views/User.vue'),
props: true
},
{
path: '/404',
name: '404',
component: () => import('./views/404.vue'),
},
]
})
If someone go to the URL of /user/some-invalid-id, how do I redirect it to the 404 page?
In my app, all user data is loaded at the App.js' breforecreate(), and internally the User view is accessed as follows for existing users
<router-link :to="{name: 'user', params:{id: u.pk}}" >
<a> {{u.first_name}} {{u.last_name}} </a>
</router-link>
I know it's possible to redirect programmatically with a push function call. But I don't know where this code should be used.
this.$router.push('/404')
In the User.vue view page, I use a vuex getter called userByID to retrieve data.
userByID: (state) => id => {
return state.users.find(u => (u.pk == id))
}
Should router.push('/404') happen in userByID or its caller? How do we deal with the template rendering with undefined user object?
I think you want to use 'Navigation Guards`, specifically a beforeEnter hook in your /user/:id route.
Something sort of like this (not tested; just directional):
routes: [
{
path: '/user/:id',
name: 'user',
component: () =>
import(/* webpackChunkName: "user" */ './views/User.vue'),
props: true,
beforeEnter: (to, from, next) => {
if (!userById($route.params.id)) {
next('/404');
}
else {
next();
}
}
}
},
{
path: '/404',
name: '404',
component: () => import('./views/404.vue'),
},
]
Note that you'll need to be able to determine if the user is valid without invoking the User.vue component.
You can also implement a beforeRouteEnter hook on User.vue directly, though you'll not be able to call other User.vue methods there as the component won't yet be mounted.
More on navigation guards: https://router.vuejs.org/guide/advanced/navigation-guards.html#global-guards
Given your userById method is accessing the store, I found this post that might help you access the store in your beforeEnter method: How to access async store data in vue-router for usage in beforeEnter hook?

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 }
]
});