Lesson 02-Nuxt.js Routing in Detail

Nuxt.js’s routing system is built on Vue Router but has been optimized and simplified to make route management more convenient for developers.

Basic Routing

Nuxt.js uses a file-based routing system, where each .vue file corresponds to a route.

Creating a Basic Page

Create a .vue file in the pages/ directory.

// pages/index.vue
<template>
  <div>
    <h1>Welcome to Nuxt.js!</h1>
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello from Nuxt.js!',
    };
  },
};
</script>

Accessible URL:

/

Dynamic Routing

Dynamic routing allows you to create different pages based on parameters.

Creating a Dynamic Page

Create a folder starting with square brackets in the pages/ directory.

// pages/posts/_id.vue
<template>
  <div>
    <h1>Post ID: {{ id }}</h1>
    <p>{{ post.title }}</p>
  </div>
</template>

<script>
export default {
  asyncData({ params, $axios }) {
    return $axios.$get(`/api/posts/${params.id}`).then(res => {
      return { post: res };
    });
  },
};
</script>

Accessible URLs:

/posts/1
/posts/2

Nested Routing

Nested routing allows you to create pages with hierarchical relationships.

Creating a Nested Page

Create nested folders in the pages/ directory.

// pages/users/_id/profile.vue
<template>
  <div>
    <h1>User Profile: {{ userId }}</h1>
    <p>{{ user.name }}</p>
  </div>
</template>

<script>
export default {
  asyncData({ params, $axios }) {
    return $axios.$get(`/api/users/${params.id}`).then(res => {
      return { user: res };
    });
  },
};
</script>

Accessible URL:

/users/1/profile

Named Routing

Named routes make it easier to reference routes in your application.

Creating a Named Route

Use the name property in a page file.

// pages/about.vue
<template>
  <div>
    <h1>About Us</h1>
  </div>
</template>

<script>
export default {
  name: 'about',
};
</script>

Referencing a Named Route:

// pages/index.vue
<template>
  <div>
    <nuxt-link :to="{ name: 'about' }">About</nuxt-link>
  </div>
</template>

Route Guards

Route guards allow you to execute logic before or after a page loads.

Page-Level Route Guard

Use the beforeEnter method.

// pages/admin/index.vue
export default {
  beforeEnter(to, from, next) {
    if (this.$store.getters.isAuthenticated) {
      next();
    } else {
      next('/login');
    }
  },
};

Global Route Guard:

// nuxt.config.js
export default {
  router: {
    middleware: ['auth'],
  },
};

// middleware/auth.js
export default function ({ store, redirect }) {
  if (!store.getters['auth/isAuthenticated']) {
    return redirect('/login');
  }
}

Route Meta Information

Route meta information allows you to add extra data to routes, such as SEO tags.

Adding Route Meta Information

Use the head method in a page file.

// pages/index.vue
export default {
  head() {
    return {
      title: 'Welcome to Nuxt.js!',
      meta: [
        { hid: 'description', name: 'description', content: 'My amazing Nuxt.js application' },
      ],
    };
  },
};

Route Redirection

Route redirection allows you to map one URL to another.

Creating a Route Redirect

Use the redirect property in a page file.

// pages/old.vue
export default {
  redirect: '/new',
};

Accessible URL:

/old (redirects to /new)

Route Aliases

Route aliases allow you to create multiple entry points for a single URL.

Creating a Route Alias

Use the alias property in a page file.

// pages/about.vue
export default {
  alias: '/info',
};

Accessible URLs:

/about
/info

Route Parameters

Route parameters allow you to retrieve dynamic values from the URL.

Retrieving Route Parameters

Use the params object in a page file.

// pages/posts/_id.vue
export default {
  asyncData({ params, $axios }) {
    return $axios.$get(`/api/posts/${params.id}`).then(res => {
      return { post: res };
    });
  },
};

Accessible URL:

/posts/1

Route Queries

Route queries allow you to retrieve values from the URL query string.

Retrieving Route Queries

Use the query object in a page file.

// pages/search.vue
export default {
  asyncData({ query, $axios }) {
    return $axios.$get(`/api/search?q=${query.q}`).then(res => {
      return { results: res };
    });
  },
};

Accessible URL:

/search?q=nuxt

Route Matching

Route matching allows you to define different handling logic for various route types.

Matching Multiple Routes

Use the path property in a page file.

// pages/contact.vue
export default {
  path: ['/contact', '/reach-us'],
  head() {
    return {
      title: 'Contact Us',
      meta: [
        { hid: 'description', name: 'description', content: 'Contact us at Nuxt.js' },
      ],
    };
  },
};

Accessible URLs:

/contact
/reach-us

Route Lazy Loading

Route lazy loading allows you to load route components on demand, improving application performance.

Using Dynamic Imports

Use import() in the asyncData method of a page file.

// pages/posts/_id.vue
export default {
  async asyncData({ params, $axios }) {
    const Post = await import('~/models/Post');
    const post = await $axios.$get(`/api/posts/${params.id}`);
    return { post: new Post(post) };
  },
};

Named Views

Named views allow you to display multiple views simultaneously on a single page.

Using Named Views

Use <nuxt-child> and <nuxt /> in a layout file.

// pages/layout.vue
<template>
  <div>
    <header>
      <nav>
        <ul>
          <li><nuxt-link to="/">Home</nuxt-link></li>
          <li><nuxt-link to="/about">About</nuxt-link></li>
        </ul>
      </nav>
    </header>
    <main>
      <nuxt-child name="sidebar" />
      <nuxt />
    </main>
    <footer>
      <p{{ new Date().getFullYear() }} My App</p>
    </footer>
  </div>
</template>

Using Named Views in Pages:

// pages/index.vue
<template>
  <div>
    <h1>Welcome to Nuxt.js!</h1>
    <p>{{ message }}</p>
  </div>
</template>

<script>
export default {
  name: 'home',
  data() {
    return {
      message: 'Hello from Nuxt.js!',
    };
  },
};
</script>

Sidebar View:

// pages/sidebar.vue
<template>
  <div>
    <h1>Sidebar</h1>
  </div>
</template>

<script>
export default {
  name: 'sidebar',
};
</script>

Specifying the Default Layout in nuxt.config.js:

// nuxt.config.js
export default {
  layout: '~/layouts/default.vue',
};

Specifying a Specific Layout in a Page:

// pages/about.vue
export default {
  layout: 'default',
};
Share your love