Vue-router: Generating URL for named child route with no path adds trailing slash.

Created on 22 Mar 2017  Â·  11Comments  Â·  Source: vuejs/vue-router

Vue.js / vue-router versions

2.2.4 / 2.3.0

Reproduction Link

http://jsfiddle.net/L7hscd8h/930/

Steps to reproduce

Generate a link for a named child route with no path so that it uses the parent route path. Look at the jsfiddle to see what I mean since it contains all the code for repro and is really small. Hover over the /user/foo link and you'll notice it shows /user/foo/ in the URL.

What is Expected?

I expected it to realize that it's a path-less route that you've generated the link for and therefore not add the trailing slash.

What is actually happening?

The trailing slash gets added in. Note, if you generate a link for the parent route user then it will correctly generate the link without the trailing slash.

I think the current situation is fine (just force them to set their parent with a name and use that to generate URLs). It was confusing and there was no warning for what I was doing. I just noticed my URLs were wrong.

I think it should either not allow creation of a path-less end child route with an error, or it should allow it and just not add the trailing slash.

Most helpful comment

@fnlctrl Hey, sorry, didn't see the question to me. The reason is that I have web server config set up to remove trailing slashes and redirect to without the trailing slash for all pages. I know this is usually common practice to make sure all your URLs follow a certain URL format.

The consistency of URLs allows me to always know what to direct to for a URL, otherwise I'd have to remember which pages have and which don't have trailing slashes, and it would just be whether or not they have a default child, which I think should be an implementation detail.

I'm curious if vue-router still needs to differentiate between user which no child routes and user.home with the default child route? Seems like it matches just fine with the URL, the only issue is that it produces a URL with a trailing. So it just seems like the code producing the URL is what requires the trailing slash? Maybe an option to collapse trailing slashes?

All 11 comments

Just saw this warning:

[vue-router] Named Route 'discover.games.view' has a default child route. When navigating to this named route (:to="{name: 'discover.games.view'"), the default child route will not be rendered. Remove the name from this route and use the name of the default child route for named links instead.

So I'm not sure what to do. When generating for the child it's adding the trailing slash. The only thing I can think of now to is force an absolute path for the child route and bypass the parent paths completely.

The children routes will always have a trailing slash. If you need the non-trailing slash version, simply use the user route in your example instead of user.home (that's what the warninng is trying to tell you). Tell me if the warning is not clear, we may need to improve the text

Hey @posva! Thanks for the quick response. Reading the error message it seems to be saying the exact opposite of that.

Remove the name from this route and use the name of the default child route for named links instead.

It is telling me to use the name of the default child route for named links instead. But when doing that, a trailing slash is added.

If I use the route user instead of user.home then it actually won't render the child content. It simply renders the content for user. If I instead link to user.home it renders the child content correctly but adds the trailing slash.

oh, right I read a bit too fast about the warning 😆
The warning doesn't actually make sense because the children does get rendered. Can you check that?

Haha, all right. Ready for some interesting weirdness? I updated the fiddle: http://jsfiddle.net/L7hscd8h/934/

All I did was change the router-link of the first link to point to the parent and not the child. Click on /user/foo link once and you'll see the child content. Click on it again and the child content disappears like magic. It acts as a toggle. haha

Except it only toggles once! You should open a new issue for that, it's probably a bug

Hmm, the warning message that it's giving makes it seem like users shouldn't be going to the parent route, though, right? Wouldn't it technically be a breaking change to start requiring them to go to parent?

It seems like the way the message is wanting should not add a trailing slash for child path-less route, and also block going to the parent directly since this will toggle will happen in that case.

Or do you think it's better to remove the warning message and instead warn them to go to parent route instead of child and to get the weird toggle thing not to happen?

Hmm, the warning message that it's giving makes it seem like users shouldn't be going to the parent route, though, right? Wouldn't it technically be a breaking change to start requiring them to go to parent?

Yes, we don't want to change that. The warning is good I think.

About your issue, it's because you have an empty child path '', that you cannot get to the parent. An empty path is like a default, and trailing slashes are present for all children, so we cannot remove that, it'll be inconsistent.

What bothers me is how the router behaves by toggling the content. But on the other hand, a warning is telling you not to do so. So on second thought, both paths are the same, that's why you should name the only the child when having an empty path child route

@fnlctrl Do you agree? A little TLDR: http://jsfiddle.net/L7hscd8h/934/ :

  • there's an empty path of a children route and named parent route
  • navigate to the parent route (users/foo)
  • The empty path child is displayed (looks ✅ to me)
  • click again on the link
  • The child disappears 😵
  • Note the warning on the console

@posva @fnlctrl Just wanted to ping so this doesn't get lost since it's still throwing me for a loop.

For some extra info, if I put the full absolute path in the child route it all works. This is what I'm doing to get around the issue, but it's frustrating since it's duplication and not as easy to change route paths. Example:

const routes = [
    { name: 'profile', path: '/user/:username', component: ..., children: [
        { name: 'profile.overview', path: '/user/:username', component: ... },
    ] },
];

When generating a link for profile.overview in the below config, it will add the trailing slash:

const routes = [
    { name: 'profile', path: '/user/:username', component: ..., children: [
        { name: 'profile.overview', path: '', component: ... },
    ] },
];

And if you instead try generating a path for profile (the parent) it will generate a path without trailing slash, but will first show child, then clicking link again will show the parent with the same link/path for the router-link.

Sorry for the late reply.. was too busy last 2 weeks..

I remember Evan saying that it's by design if you use a name to navigate (router-link, $router.push..), it will match the exact named route(with no child routes). It was designed for cases where you want to explicitly display the parent route with empty child route.

As for the fiddle http://jsfiddle.net/L7hscd8h/934/ (Thanks for the tl,dr; @posva )
If you do as the warning says (remove the parent name, and use the child name), everything works fine.
http://jsfiddle.net/kLkg3tkt/

@hworld Out of curiosity, why would the trailing slash be an issue? It was used by vue-router to differentiate 'user'(no child routes) from 'user.home'(default child route).
If you would never need to display an empty parent route, you can simply use the name on the default child route instead.

@fnlctrl Hey, sorry, didn't see the question to me. The reason is that I have web server config set up to remove trailing slashes and redirect to without the trailing slash for all pages. I know this is usually common practice to make sure all your URLs follow a certain URL format.

The consistency of URLs allows me to always know what to direct to for a URL, otherwise I'd have to remember which pages have and which don't have trailing slashes, and it would just be whether or not they have a default child, which I think should be an implementation detail.

I'm curious if vue-router still needs to differentiate between user which no child routes and user.home with the default child route? Seems like it matches just fine with the URL, the only issue is that it produces a URL with a trailing. So it just seems like the code producing the URL is what requires the trailing slash? Maybe an option to collapse trailing slashes?

Was this page helpful?
0 / 5 - 0 ratings