Repository: nuxt/nuxt.js
Pull request #6594 (2019-10-20 14:02:02)

fix(router): show default child if trailingSlash is false
Resolves https://github.com/nuxt/nuxt.js/issues/6593

The bug was introduced by setting `'/'` instead of `''` for child routes when `router.trailingSlash` is `false`:
 https://github.com/nuxt/nuxt.js/blob/e39f54b44e203f6c47100f8fd779f34345bac772/packages/utils/src/route.js#L184.

## Types of changes

- [x] Bug fix (a non-breaking change which fixes an issue)
- [ ] New feature (a non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)


## Checklist:
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly. (PR: #)
- [ ] I have added tests to cover my changes (if not applicable, please state why)
- [ ] All new and existing tests are passing.



manniL: I kept the failing tests because I'm not sure about the impact of the introduced change and love to get feedback on the PR.
pimlie: The failing test seems to be an issue, adding the `?` to the route param will now also match the route when no param is given. In the test that might not be an issue because `projects` is already listed before, but if a user doesnt want to match `/projects` at all then this is a breaking change I guess?
manniL: My check for `trailingSlash` was wrong, thus the weird result. Should be fine with the latest commit.
manniL: Ready for review :relaxed: 
pimlie: Sorry for asking but why is deleting the name of the route the solution? It isnt something thats immediately obvious to me.
manniL: @pimlie Valid question! As reported in https://github.com/nuxt/nuxt.js/issues/6593, 

pimlie: Thanks. Isnt deleting the route name then strictly speaking resolving a consequence of an issue? Ie why are the route names duplicate in the first place?

If it isnt solvable by fixing the duplicate route names, could we maybe add a comment explaining why we choose to fix it this way?
manniL: @pimlie Not sure why there were duped route names initially. Maybe @clarkdo could provide more info 🤔 
pimlie: I think its because of this replace: https://github.com/nuxt/nuxt.js/blob/dev/packages/utils/src/route.js#L64

Because of that `my-route` and `my-route/index` will both be named `my-route`.
RettuSh: Hi! Is there any change to fix this bug soon? Could I help you somehow?
ems1985: Hi, any updates on this?

Just FYI the issue also presents itself when ```router.trailingSlash``` is set to ```true```

This is my folder structure:
![image](https://user-images.githubusercontent.com/34405275/82030008-1f25fc80-9698-11ea-9fc1-74dd058923e3.png)

Without the trailingSlash option my router.js routes looks like this:
```
routes: [{
    path: "/something",
    component: _2eb15426,
    children: [{
      path: "",
      component: _0e04f6b0,
      name: "something"
    }, {
      path: "childcomponent",
      component: _4484dbf3,
      name: "something-childcomponent"
    }]
  }, {
    path: "/",
    component: _d1bba076,
    name: "index"
  }],
```

With ```router.trailingSlash``` set to ```true``` 
```
routes: [{
    path: "/something/",
    component: _2eb15426,
    pathToRegexpOptions: {"strict":true},
    name: "something",
    children: [{
      path: "childcomponent/",
      component: _4484dbf3,
      pathToRegexpOptions: {"strict":true},
      name: "something-childcomponent"
    }, {
      path: "",
      component: _0e04f6b0,
      pathToRegexpOptions: {"strict":true},
      name: "something"
    }]
  }, {
    path: "/",
    component: _d1bba076,
    pathToRegexpOptions: {"strict":true},
    name: "index"
  }]
```

Of course results in the following warnings:
```
 WARN  [vue-router] Named Route 'something' has a default child route. When navigating to this named route (:to="{name: 'something'"), 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.


 WARN  [vue-router] Duplicate named routes definition: { name: "something", path: "/something/" }  
```
codecov-commenter: # [Codecov](https://codecov.io/gh/nuxt/nuxt.js/pull/6594?src=pr&el=h1) Report
> Merging [#6594](https://codecov.io/gh/nuxt/nuxt.js/pull/6594?src=pr&el=desc) into [dev](https://codecov.io/gh/nuxt/nuxt.js/commit/2e5bc24f44d2278a3e01a76335b394b8bb21233f&el=desc) will **increase** coverage by `0.03%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/nuxt/nuxt.js/pull/6594/graphs/tree.svg?width=650&height=150&src=pr&token=nGD1PtMB3M)](https://codecov.io/gh/nuxt/nuxt.js/pull/6594?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##              dev    #6594      +/-   ##
==========================================
+ Coverage   70.14%   70.17%   +0.03%     
==========================================
  Files          88       88              
  Lines        3758     3762       +4     
  Branches     1020     1022       +2     
==========================================
+ Hits         2636     2640       +4     
  Misses        912      912              
  Partials      210      210              
```

| Flag | Coverage Δ | |
|---|---|---|
| #unittests | `70.17% <100.00%> (+0.03%)` | :arrow_up: |

| [Impacted Files](https://codecov.io/gh/nuxt/nuxt.js/pull/6594?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [packages/utils/src/route.js](https://codecov.io/gh/nuxt/nuxt.js/pull/6594/diff?src=pr&el=tree#diff-cGFja2FnZXMvdXRpbHMvc3JjL3JvdXRlLmpz) | `96.66% <100.00%> (+0.09%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/nuxt/nuxt.js/pull/6594?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/nuxt/nuxt.js/pull/6594?src=pr&el=footer). Last update [2e5bc24...0fdd55b](https://codecov.io/gh/nuxt/nuxt.js/pull/6594?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/packages/utils/src/route.js b/packages/utils/src/route.js
index 95dc8f238..cc619c187 100644
--- a/packages/utils/src/route.js
+++ b/packages/utils/src/route.js
@@ -30,7 +30,7 @@ export const flatRoutes = function flatRoutes (router, fileName = '', routes = [
   return routes
 }
 
-function cleanChildrenRoutes (routes, isChild = false, routeNameSplitter = '-') {
+function cleanChildrenRoutes (routes, isChild = false, routeNameSplitter = '-', trailingSlash) {
   let start = -1
   const regExpIndex = new RegExp(`${routeNameSplitter}index$`)
   const routesIndex = []
@@ -68,10 +68,15 @@ function cleanChildrenRoutes (routes, isChild = false, routeNameSplitter = '-')
     }
     route.name = route.name.replace(regExpIndex, '')
     if (route.children) {
-      if (route.children.find(child => child.path === '')) {
+      const indexRoutePath = trailingSlash === false ? '/' : ''
+      const defaultChildRoute = route.children.find(child => child.path === indexRoutePath)
+      if (defaultChildRoute) {
+        if (trailingSlash === false) {
+          defaultChildRoute.name = route.name
+        }
         delete route.name
       }
-      route.children = cleanChildrenRoutes(route.children, true, routeNameSplitter)
+      route.children = cleanChildrenRoutes(route.children, true, routeNameSplitter, trailingSlash)
     }
   })
   return routes
@@ -188,7 +193,7 @@ export const createRoutes = function createRoutes ({
   })
 
   sortRoutes(routes)
-  return cleanChildrenRoutes(routes, false, routeNameSplitter)
+  return cleanChildrenRoutes(routes, false, routeNameSplitter, trailingSlash)
 }
 
 // Guard dir1 from dir2 which can be indiscriminately removed


Test patch:
diff --git a/packages/utils/test/__snapshots__/route.test.js.snap b/packages/utils/test/__snapshots__/route.test.js.snap
index 1285e2b64..9731bddd9 100644
--- a/packages/utils/test/__snapshots__/route.test.js.snap
+++ b/packages/utils/test/__snapshots__/route.test.js.snap
@@ -260,7 +260,6 @@ Array [
     ],
     "chunkName": "pages/another_route/_id",
     "component": "/some/nuxt/app/pages/another_route/_id.vue",
-    "name": "another_route-id",
     "path": "/another_route/:id?",
     "pathToRegexpOptions": Object {
       "strict": true,