I want bad routes to navigate to the root route. I've added a mapUnknownRoutes configuration on my router.
config.mapUnknownRoutes((inst) => inst.config.moduleId = 'home');
But this leaves the route untouched. For example, #/fakeRoute routes to home. Ideally, I would like a behavior similar to returning { redirect: '#/' }, which cancels navigation and creates a new navigation to the route '#/'. Is this a feature?
The mapUnknownRoutes method also accepts a RouteConfig object so you can just directly specify your redirect there:
config.mapUnknownRoutes({ redirect: '#/' });
See the complete signature of the method on github
Related
It's basically a simple task: I'm using Vue3 with the Vue Router, there's my Home.vue component which lives in the / route, then there's a ProductDetails.vue component which lives in the /product route.
I want to execute a certain action when the user is navigating to my / route. However, I only want this action to happen when the user directly navigates here, meaning via clicking a link or via the browser's URL bar. I don't want the action to execute when he is navigating back from ProductsDetails.vue (or routing via "back" from anywhere, for that matter).
How do I achieve this with Vue3 or Vue Router methods? I know I can probably do it with query parameters in my URL but I'd prefer not to.
You could use in-component navigation guards (read more about it here (options api) OR here (composition api))
Your code could look something like this
...
beforeRouteEnter(to, from, next) {
if(from.path === '/') {
// do something
}
},
...
I have a lot of articles in my app, and the URL are written like this in Vue Router: /article/:id.
I have particular articles I want to "pin" and have easier URLs. For example: /pinned-article, which should point to /article/3274 and /other-pinned-article, pointing to /article/68173.
I though about adding this to my routes, but it doesn't work:
{ path: '/article/3274', component: Article, alias: '/pinned-article' }
I thought about something else, involving another component:
{ path: '/pinned-article/:id', component: PinnedArticle }
The component PinnedArticle silently aliasing the correct article with a command like router.alias in the <script> section, but it apparently doesn't exist.
Is there a way to solve this problem? I thought I could use some answers I read here in Stackvoverflow (for examples when it comes to redirect /me to /user/:id, but it doesn't apply.
Thanks in advance :)
addRoute
You can achieve this with Dynamic Routing, which is not the same as dynamic route matching, i.e. route params.
(This solution works in both Vue 3 and Vue 2 with Vue Router >= 3.5.0)
By using the addRoute method of Vue router, you can create routes at runtime. You can either use a redirect or not, depending on whether you want the url bar to read /article/3274 or /pinned.
Redirect
If you want the url to change from /pinned to /article/3274, use redirect:
methods: {
pinRoute() {
this.$router.addRoute({
path: '/pinned',
name: 'pinned',
redirect: { name: 'article', params: { id: 3274 }}
})
}
}
Access the route like:
this.$router.push('/pinned')
The above example assumes you give your Article route a name: 'article' property so you can redirect to it
Alias
You can keep the URL as /pinned using alias. Normally the alias would go on the existing Article route definition, but that doesn't work well with route params. You can use a "reverse alias" with a new route:
methods: {
pinRoute() {
this.$router.addRoute({
path: '/params/3274',
name: 'pinned',
alias: '/pinned',
component: () => import('#/views/Article.vue') // Article component path
})
}
}
Access the route like:
this.$router.push('/pinned')
Notes:
You'll probably want to pass an id argument to the pinRoute methods rather than hardcode them like in the examples above.
A nice thing about addRoute with either method above is if the route already exists, say, from the last time you called the method, it gets overwritten. So you can use the method as many times as you like to keep changing the destination of /pinned. (The docs in both Vue 2 and Vue 3 say the route definition will get overwritten, though Vue 2 router throws a duplicate route warning.)
Of course the pinned route won't automatically persist between app refreshes, so you'll need to save/load the pinned id (i.e. using localStorage, etc.) and run one of these methods on app load if you want that
I'm getting some issues when trying to redirect to an external link.
for ex:
{ path: '*', redirect: 'https://google.com'}
when I use "redirect" it doesn't work completely, but when I use something like that
{ path: '/*',
beforeEnter(to, from, next) {
window.location = "https://google.com"
}
}
it works but there is a problem because first, it tries to render App component again but there is no component so be empty and a blank page is being rendered for nearly 1-1.5 second then it redirects to target URL and I don't want it to reload App component, just redirect it to other link. I googled but found nothing noteworthy.
Or maybe is there another way like deactive a component or use v-if or directly rendering a html file?
redirect is meant to redirect to another route defined by your application, not to go to another website directly.
window.location works, but I think the behavior is somewhat browser-dependent.
I have a project it's routing strucher is like this.
1. /
2. admin-panel/:type
2.1 create-user
2.2 update-user
2.3 etc...
3. forgot password
My problem is if someone come to the admin-panel/:type,he has to route to the create-user
by default.
I used a tricky way for this which is create root route under the admin-panel/:type
like this
2.admin-panel
2.1 /
2.2 create-user
But this doesn't work this time since the admin-panel has a parameter called type.
I want if someone comes to the admin-panel he should directed to the create-user by default. How do I achieve this?
I've to add redirect property to the admin-panel route.
Personally for these cases I use an afterEach hook in the routes file:
router.afterEach((to, from) => {
let exist = false
for (let i in this.a.options.routes) {
if (this.a.options.routes[i].name === to.name) {
exist = true
}
}
if (!exist) {
this.a.push({
name: from.name
})
}
})
You can use another hook as beforeEach (I do not remember exactly why we use after). Basically the goal is to go through the list of routes, if it does not exist, it returns you to the route you are currently on, which really means that you do not notice any changes, it just does not change the route.
How do I specify a catchall or actually a catch[most] for express so when the user selects refresh on a page that is actually contained in the app bundle, the GET doesn't fail.
home.html
profile
app.js
config.map([
{ route: ['', 'home'], name: 'home', moduleId: 'home' },
{ route: ['profile'], name: 'profile', moduleId: './profile/profile'}
]);
If I click on the profile link, the URL shows localhost://profile and the page renders correctly without performing a GET because the requested resource was bundled in the initial GET. But lets say I refresh the page with localhost://profile, then it makes a server GET request for that page.
If on the server I specify something like:
app.use('/', express.static(__dirname));
app.use('/profile', express.static(__dirname));
It works properly. I was anticipating some type of catch all formatting so I don't have to add every possible route for an app with all routes bundled. Something like:
app.use('/*', express.static(__dirname));
Then the following to capture GET's for another app
app.use('/othercoolapp/*', express.static(__dirname)+'/othercoolapp/');
But it doesn't work...
This issue you're encountering applies to every single page application framework and library with pushState routing enabled.
Above your app.listen or equivalent line of code in the file that bootstraps your Express server, add something like this:
app.get('*', function(request, response){
response.sendFile(path.join(__dirname + '/index.html'));
});
The general idea is that this generic wildcard route will capture all URL requests and send the index.html file. This allows Aurelia to handle its own routing.