Vue router not matching route with more than one slash - vue.js

basically my issue is that I want to pass a router prop called name into an article route, so something like /article/:name. When I direct to that route internally, like with $router.push(name: 'article', params: {name: 'something'}), it works just fine. But when I then use that url, /article/something, the route doesn't match and the page is blank.
But if I just use /:name instead of /article/:name, everything works just fine. Does anyone have any idea why the /article part could be causing the route to fail to match? Thanks in advance.
EDIT: Route definition:
{
path: '/article/:name',
name: 'article',
component: () => import('../views/Article.vue'),
props: true,
}
When I navigate to /article/something, the page is blank, no matter what something is. But if I have the following route definition:
{
path: '/:name',
name: 'article',
component: () => import('../views/Article.vue'),
props: true,
}
and navigate to /something, it works just fine.

Related

How to change base url in VUE router?

Current URL is 'https://localhost:3000/lang/countries/states/cities/'
I want to change it to:
https://localhost:3000/lang/compare/?c=1&back=1&query=94&query=911
Basically I want to edit the current URL. I tried using:
this.$router.push({
path:'/lang/compare/?c=1&back=1&query=94&query=911',
});
this.$router.replace({
path:'/lang/compare/?c=1&back=1&query=94&query=911',
});
But this changes the URL to :
https://localhost:3000/lang/countries/states/cities/lang/compare/?c=1&back=1&query=94&query=911',
I have tried using window location href but coz of that state of my variable is lost, hence I need to use VUE router for this. Is their any way to change base URL in VUE routes.
Your method is also right it should work if there is no other issue,
try with
this.$router.push({ path: '/lang/compare', query: { c: 1,back:1,firstquery:94,queryB:991}})
or you can also try with $router name defining a name on router index file
{
path: "/lang/compare",
name: "compare",
component: comparePage,
},
this.$router.push({ name: 'compare', query: { c: 1,back:1,firstquery:94,queryB:991}})

Optional route params with Vue Router

In my Vue 2.7.5 app (using Vue Router 3.5.4) I'm trying to define this route
{
path: '/messages/:messageId?/replies/:replyId?',
name: 'messages',
component: () => import('#/views/messages')
}
The intent is
to see all messages use /messages
to see a specific message use /messages/:messageId
To see a specific message and a specific reply to that message use /messages/:messageId/replies/:replyId
However, if I navigate to this route without specifying any route params using
<router-link :to="{name: 'messages'}">
Then the URL is resolved as /messages/replies, but I would like it to be resolved as /messages.
Essentially, what I want is: don't include /replies unless there's a replyId param, but I don't know how to express that.
One solution is to use the following instead:
<router-link :to="{ path: '/messages'}">
But I prefer to always refer to routes by name, because this gives me the flexibility to change the paths without breaking anything
The easiest solution for you is to remove /replies and only have path like this:
'/messages/:messageId?/:replyId?'
(Optional solution)
If removing that part of url is not an option and using named routes is a must, here is an alternative solution where you use two named routes. If the replyId is missing you can redirect before enter to the 2nd named route.
{
path: '/messages/:messageId?/replies/:replyId?',
name: 'message-replies',
component: () => import('#/views/messages'),
beforeEnter({ params }) {
if (!params.replyId) {
return {
name: 'messages',
params: {
messageId: params.messageId,
},
};
}
},
},
{
path: '/messages/:messageId?',
name: 'messages',
component: () => import('#/views/messages'),
},

Vuejs show product page in combination with repeatable route params as nested categories

I would like to access a product details page within the set of categories.
For example: website.com/catalog/cat1/cat2/cat3/product-item-123
I'm using a Repeatable params to construct a nested set of categories, so URL would look like this which works fine:
website.com/catalog/category/subcategory/anothersubcateg/
{
path: '/catalog/:slug+',
name: 'category.show',
component: () => import('pages/category.show.vue'),
props: route => ({ slug: route.params.slug })
},
But when I add a new route rule it overrides all pages for categories and shows a product page instead:
{
path: '/catalog/:slug+/:productSlug',
name: 'product.show',
component: () => import('pages/product.show.vue'),
props: route => ({ slug: route.params.slug })
}
How to render a pages/product.show.vue file only when the product page is opened and not override the pages/category.show.vue file ?
UPDATED
Here is the list of URLs I would like to have:
format: /CAT+/PRODUCT_ID-PRODUCT_SLUG
/clothes/t-shirts/winter/men/20380-underarmor-crossfit-99x
/hardware/gpus/87689-nvidia-rtx-3080ti-24gb
/smartphones/ios/iphone-13-pro-512gb
As you cannot use regex to help you sort products from categories, the simplest solution seems to be to add a separator section to your url to tell the router that what follows is a product:
path: '/catalog/:slug+/product/:productSlug',
Tell me if you're still facing an issue. Happy coding!

Vue redirect back to '/' if 404 not found

I have a Vue application with the following routes:
export default new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'input',
component: Input
},
{
path: '/result/:city',
name: 'result',
component: Result
}
]
})
I know that if I do a new path with path: '*' and component: someErrorPage, I can show an error page. However, I'd like to redirect back to the input path so they can try again.
EDIT:
After doing some research and looking at my app, I found that if I search an invalid query, it will take me to corresponding route anyway, but not show me the data. Example: If I search a valid city (eg. New York), I am redirected to localhost:8080/result/New York with the correct data. However, if I do an in valid query (eg. a;fldkalf), I will be taken to localhost:8080/result/a;fldkalf without any data. This means that path: '*' will not help me here.
EDIT 2:
I think I may have found something that will help, but I am not sure how to execute it. Vue has something called navigation guards (https://router.vuejs.org/guide/advanced/navigation-guards.html#global-before-guards). If someone could help me make sense of it, that'd be great.
You can add redirect for * (not found) route:
{
path: '*', // make sure this is the last route in Array
redirect: { name: 'input' },
}

How to redirect non-dynamic urls with vue-router

We have a vue.js app for an insurance company where every agent has their own dynamically-generated website. Currently, if you visit a gibberish link, it will show the blank agent template. We need urls that don't include an agent's slug to redirect to our "NotFound" component.
Below is our vue-router code if there happens to be an easy fix. Otherwise is it easier to add a computed function to redirect a visitor if, for example, the agent.name == null?
Thanks for any help!
Example of a good url: https://my.piaselect.com/georgebeach
Example of a bad url: https://my.piaselect.com/georgebeach2
Our router:
{
path: "/:id",
component: AgentSite,
name: 'AgentSite',
props: true
},
{
path: '*',
name: 'NotFound',
component: NotFound
}
Building on what #Jacob Goh has said.
You need a way to to now if the agent id is valid or not. Let's assume you have a list of agent id's, you can use a route guard to block the route to invalid ids.
https://router.vuejs.org/en/advanced/navigation-guards.html
I haven't tested this, but you should be able to get the general idea.
const agentIds = ['Bob', 'Michael']
const router = new VueRouter({
routes: [
{
path: '/foo:id',
component: Foo,
beforeEnter: (to, from, next) => {
if (agentIds.includes(to.params.id)) {
// The agent is fine - continue
next();
} else {
// doesn't exist - go back to root or any other page
next({ path: '/' });
}
}
}
]
})
it doesn't work because you don't specify any name in this path :
{
path: "/:id",
component: AgentSite,
name: 'AgentSite',
props: true
},
because of that, this path allow any random chars at the root to return the component AgentSite (but blank because the random chars "param" fit to nothing in the component i guess).
To prevent that, you can specify a name to your path : path: "agent/:id" for example.
Edit : it seems you already had a great solution here...