Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Discussion options

What problem is this solving

I'm pretty sure this isn't possible today, but I'd be curious if I'm thinking about this problem correctly, and if so would love to propose extending the existing resolver functionality. Here's the gist:

Our application has a ton of routes, most of which fall into a single parent that looks something like /foo/:namespace. When navigating between these routes, we like to assume we already have access to the :namespace param, and omit it from our route objects. For instance, if we need to go to /foo/:namespace/stats, which has route name StatsPage, we'll call $router.push({ name: 'StatsPage' }), omitting the params: { namespace: '123' }. It's worth noting that a user only ever interfaces with the app in the context of a single namespace at a time, so we can essentially always assume the namespace is whatever the users currently active namespace is.
However, not all of our routes fit this pattern. For instance, if we have several routes that end up looking like /global/thing. In these cases, the above $router.push({ name: 'StatsPage' }) needs to have a resolve hook that injects the namespace value for the user. This all works totally fine today when navigating programmatically via router pushes, because global/route layer beforeResolve hooks can inject what we need.
The problem comes in when we need to generate clickable hrefs - $router.resolve doesn't call any custom resolvers, meaning if we're on route /global, any generated hrefs to namespaced routes throw errors because they can't resolve :namespace. Effectively, this means for anything that might live on a global page that also needs to produce an href outside of a <router-link>, we can't take shortcuts with assuming the :namespace.

Proposed solution

Obviously there are lots of ways to solve this in userland, but I've noticed it can also be solved via this little hack of overloading the router's native resolve:

const original = router.resolve;

router.resolve = (to, currentLocation = {}) => {
    to.params = {
        ...to.params,
        namespace: currentLocation.params?.namespace || store.state.namespace.id
    };

    return original(to, currentLocation);
}

This is effectively just a beforeResolve hook, but applied to the routers resolve method directly, vs only being applied at time of navigation. This allows us to generate links from anywhere in the codebase by directly calling the routers standard api $router.resolve, vs needing to have a helper function/composable/etc that devs need to know to use whenever they generate an href.

I'm positive blindly saying "also apply the global beforeResolve hook to matcher.resolve" would result in a ton of problems, but it would be awesome to have something like:

router.matcherBeforeResolve = (to, currentLocaiton) => {
  // return modified object that gets passed to `router.resolve(to, currentLocation)`
  return {
    ..to,
    params: {
      ...to.params,
      new: 'param'
    }
};

This would run directly before the matcher attempts to resolve to a route, passing the output of the function to the normal router.resolve. For what its worth, assuming this isn't already possible, and makes sense to add, I'm happy to put up a draft PR to get this going

Describe alternatives you've considered

Today we solve this problem via a composable, but having to pull a compsable in all over the place just to do this feels kinda goofy and results in a lot of duplication, while also being more "app specific knowledge" a dev needs to understand about the system

You must be logged in to vote

Replies: 1 comment · 2 replies

Comment options

I think that with the upcoming #2415 (resolvers are the new matchers), you should be able to override the resolve method to add your customization.

By the description of the problem, this sounds like a convenience helper that allows you to omit a param. I think this will create other problems down the line, for example in typed routes but it's worth a discussion so people can share use cases. I'm particularly interested in use cases beyond convenience.

You must be logged in to vote
2 replies
@4storia
Comment options

oh nice! yeah it actually does sound like that would be exactly what we need. And you're right that at least for us it is definitely more of a convenience, rather than a hard blocker. We have a lot of urls that get opened in new windows via window.open($router.resolve(...)), so we basically end up replicating the same param convenience for those cases that we also use inside our custom <router-link> and our router.beforeResolve hook, hence me trying to find a way to holistically do it all in one spot.

We don't use typescript so I can't speak at all to the typed routes component, but being able to override the resolve method in a way thats sanctioned by the library (instead of just literally overwriting it 😂 ) sounds like exactly what we want!

@4storia
Comment options

@posva Figured i'd ask as well, is the above mentioned PR part of an upcoming release, or have a rough timeframe associated with it? I just ask because it's been open for quite a while - definitely not asking for dates or anything like that, more just what the rough release plan is

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
💡
Ideas
Labels
None yet
2 participants
Converted from issue

This discussion was converted from issue #2510 on June 03, 2025 14:54.

Morty Proxy This is a proxified and sanitized view of the page, visit original site.