diff --git a/lib/build/index.js b/lib/build/index.js
index 8e5f488527..8d47588799 100644
--- a/lib/build/index.js
+++ b/lib/build/index.js
@@ -198,15 +198,23 @@ function createRoutes (files, srcDir) {
let route = { name: '', path: '', component: r(srcDir, file), _name: null }
let parent = routes
keys.forEach((key, i) => {
- route.name = route.name ? route.name + (key === 'index' ? '' : '-' + key.replace('_', '')) : key.replace('_', '')
+ route.name = route.name ? route.name + '-' + key.replace('_', '') : key.replace('_', '')
let child = _.find(parent, { name: route.name })
if (child) {
if (!child.children) {
child.children = []
}
parent = child.children
+ route.path = ''
} else {
- route.path = route.path + (key === 'index' ? (i > 0 ? '' : '/') : '/' + key.replace('_', ':'))
+ if (key === 'index' && (i + 1) === keys.length) {
+ route.path += (i > 0 ? '' : '/')
+ } else {
+ route.path += '/' + key.replace('_', ':')
+ if (key.includes('_')) {
+ route.path += '?'
+ }
+ }
}
})
route._name = '_' + hash(route.component)
@@ -222,15 +230,22 @@ function createRoutes (files, srcDir) {
}
function cleanChildrenRoutes (routes, isChild = false) {
- let isOptional = true
+ let hasIndex = false
+ let parents = []
routes.forEach((route) => {
route.path = (isChild) ? route.path.replace('/', '') : route.path
- if (route.path === '' || route.path === '/') {
- isOptional = false
+ if ((isChild && /-index$/.test(route.name)) || (!isChild && route.name === 'index')) {
+ hasIndex = true
}
- if (isOptional && route.path.includes(':')) {
- route.path += '?'
+ route.path = (hasIndex) ? route.path.replace('?', '') : route.path
+ if (/-index$/.test(route.name)) {
+ parents.push(route.name)
+ } else {
+ if (parents.indexOf(route.name.split('-').slice(0, -1).join('-') + '-index') > -1) {
+ route.path = route.path.replace('?', '')
+ }
}
+ route.name = route.name.replace(/-index$/, '')
if (route.children) {
delete route.name
route.children = cleanChildrenRoutes(route.children, true)
diff --git a/test/fixtures/dynamic-routes/README.md b/test/fixtures/dynamic-routes/README.md
new file mode 100644
index 0000000000..a6a85d97ad
--- /dev/null
+++ b/test/fixtures/dynamic-routes/README.md
@@ -0,0 +1,185 @@
+# Defining custom routes with Nuxt.js
+
+> Nuxt.js is based on `vue-router` and let you to defined custom routes easily :rocket:
+
+## Concept
+
+Nuxt.js generates automatically the `vue-router` configuration according to your file tree of `.vue` files inside the `pages/` directory.
+
+## Basic routes
+
+This file tree:
+
+```bash
+pages/
+--| team/
+-----| index.vue
+-----| about.vue
+--| index.vue
+```
+
+will automatically generate:
+
+```js
+router: {
+ routes: [
+ {
+ name: 'index',
+ path: '/',
+ component: 'pages/index.vue'
+ },
+ {
+ name: 'team',
+ path: '/team',
+ component: 'pages/team/index.vue'
+ },
+ {
+ name: 'team-about',
+ path: '/team/about',
+ component: 'pages/team/about.vue'
+ }
+ ]
+}
+```
+
+## Dynamic routes
+
+To define a dynamic route with a param, you need to define a `.vue` file **prefixed by an underscore**.
+
+This file tree:
+
+```bash
+pages/
+--| users/
+-----| _id.vue
+-----| index.vue
+```
+
+will automatically generate:
+
+```js
+router: {
+ routes: [
+ {
+ name: 'users',
+ path: '/users',
+ component: 'pages/users/index.vue'
+ },
+ {
+ name: 'users-id',
+ path: '/users/:id',
+ component: 'pages/users/_id.vue'
+ }
+ ]
+}
+```
+
+### Additional feature: validate (optional)
+
+Nuxt.js lets you define a validator function inside your dynamic route component (In this example: `pages/users/_id.vue`).
+
+If the validate method does not return `true`, Nuxt.js will automatically load the 404 error page.
+
+```js
+
+```
+
+## Nested Routes (children)
+
+To define a nested route, you need to create a `.vue` file with the **same name as the directory** which contain your children views.
+> Don't forget to put `` inside your parent `.vue` file.
+
+This file tree:
+
+```bash
+pages/
+--| users/
+-----| _id.vue
+--| users.vue
+```
+
+will automatically generate:
+
+```js
+router: {
+ routes: [
+ {
+ path: '/users',
+ component: 'pages/users.vue',
+ children: [
+ {
+ path: ':id',
+ component: 'pages/users/_id.vue',
+ name: 'users-id'
+ }
+ ]
+ }
+ ]
+}
+```
+
+## Dynamic Nested Routes
+
+This file tree:
+
+```bash
+pages/
+--| posts/
+-----| _slug/
+--------| _name.vue
+--------| comments.vue
+-----| _slug.vue
+-----| index.vue
+--| posts.vue
+```
+
+will automatically generate:
+
+```js
+router: {
+ routes: [
+ {
+ path: '/posts',
+ component: 'pages/posts.vue',
+ children: [
+ {
+ path '',
+ component: 'pages/posts/index.vue',
+ name: 'posts'
+ },
+ {
+ path: ':slug',
+ component: 'pages/posts/_slug.vue',
+ children: [
+ {
+ path: 'comments',
+ component: 'pages/posts/_slug/comments.vue',
+ name: 'posts-slug-comments'
+ },
+ {
+ path: ':name',
+ component: 'pages/posts/_slug/_name.vue',
+ name: 'posts-slug-name'
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
+```
+
+## Demo
+
+```bash
+npm install
+npm start
+```
+
+Go to [http://localhost:3000](http://localhost:3000) and navigate through the pages.
diff --git a/test/fixtures/dynamic-routes/nuxt.config.js b/test/fixtures/dynamic-routes/nuxt.config.js
new file mode 100644
index 0000000000..bb0765f744
--- /dev/null
+++ b/test/fixtures/dynamic-routes/nuxt.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ build: {
+ vendor: ['axios']
+ }
+}
diff --git a/test/fixtures/dynamic-routes/package.json b/test/fixtures/dynamic-routes/package.json
new file mode 100644
index 0000000000..31c9724fdb
--- /dev/null
+++ b/test/fixtures/dynamic-routes/package.json
@@ -0,0 +1,13 @@
+{
+ "name": "nuxt-custom-routes",
+ "description": "",
+ "dependencies": {
+ "axios": "^0.15.2",
+ "nuxt": "latest"
+ },
+ "scripts": {
+ "dev": "nuxt",
+ "build": "nuxt build",
+ "start": "nuxt start"
+ }
+}
diff --git a/test/fixtures/dynamic-routes/pages/_key/_id.vue b/test/fixtures/dynamic-routes/pages/_key/_id.vue
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/fixtures/dynamic-routes/pages/_slug.vue b/test/fixtures/dynamic-routes/pages/_slug.vue
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/fixtures/dynamic-routes/pages/parent.vue b/test/fixtures/dynamic-routes/pages/parent.vue
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/fixtures/dynamic-routes/pages/parent/child.vue b/test/fixtures/dynamic-routes/pages/parent/child.vue
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/fixtures/dynamic-routes/pages/parent/index.vue b/test/fixtures/dynamic-routes/pages/parent/index.vue
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/fixtures/dynamic-routes/pages/parent/teub.vue b/test/fixtures/dynamic-routes/pages/parent/teub.vue
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/fixtures/dynamic-routes/pages/test/index.vue b/test/fixtures/dynamic-routes/pages/test/index.vue
new file mode 100644
index 0000000000..94414546d1
--- /dev/null
+++ b/test/fixtures/dynamic-routes/pages/test/index.vue
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
diff --git a/test/fixtures/dynamic-routes/pages/test/users.vue b/test/fixtures/dynamic-routes/pages/test/users.vue
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/fixtures/dynamic-routes/pages/test/users/_id.vue b/test/fixtures/dynamic-routes/pages/test/users/_id.vue
new file mode 100644
index 0000000000..ccd6594097
--- /dev/null
+++ b/test/fixtures/dynamic-routes/pages/test/users/_id.vue
@@ -0,0 +1,33 @@
+
+
+
{{ name }}
+
@{{ username }}
+
Email : {{ email }}
+
List of users
+
+
+
+
+
+
diff --git a/test/fixtures/dynamic-routes/pages/test/users/_index/teub.vue b/test/fixtures/dynamic-routes/pages/test/users/_index/teub.vue
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/fixtures/dynamic-routes/pages/test/users/index.vue b/test/fixtures/dynamic-routes/pages/test/users/index.vue
new file mode 100644
index 0000000000..e69de29bb2