#Issues with Nested routing

5 messages · Page 1 of 1 (latest)

west cradle
#

Hello,
I am having hard time with nested routing.
I have roles, guest, user and admin roles, and want to restrict guest from accessing user and admin routes, once logged in restrict user from accessing admin's routes and vice versa.
I have added middleware to index.vue inside the folder but it only guards index file. I am looking for middleware guard all the files in the folder.

here is the structure of the folder
--pages
|--index.vue
|--Investor // Parent Folder
|--index.vue // Parent Main page
|--overview.vue // Child page
|--profile.vue // Child page

noble pilotBOT
#

Hi @west cradle. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

I understand you're having issues with nested routing and middleware in Nuxt, specifically with protecting routes based on user roles.

The issue you're facing is that middleware applied to the parent index.vue file doesn't automatically apply to all child routes in the folder. Let's solve this problem.

Solution: Global Middleware for Role-Based Access

You have a few options to protect all routes in a folder:

Option 1: Create a global middleware

Create a global middleware file that checks user roles and restricts access accordingly:

// middleware/auth.global.ts
export default defineNuxtRouteMiddleware((to) => {
  // Get user role from your auth store/service
  const userRole = getUserRole() // implement this based on your auth system
  
  // Define route access rules
  if (to.path.startsWith('/Investor') && userRole === 'guest') {
    return navigateTo('/login') // or wherever you want to redirect
  }
  
  if (to.path.startsWith('/admin') && userRole !== 'admin') {
    return navigateTo('/')
  }
  
  // Add more path checks as needed
})

Global middleware runs on every route change, so this will protect all your routes Docs > Guide > Directory Structure > Middleware.

Option 2: Apply middleware to each page

You can add the middleware to each page using definePageMeta:

<script setup>
definePageMeta({
  middleware: ["auth"]
})
</script>

However, this would be repetitive as you'd need to add it to every page.

Option 3: Set middleware at build time

A more elegant solution is to use the pages:extend hook in your nuxt.config.ts to apply middleware to all pages in specific directories:

#
// nuxt.config.ts
export default defineNuxtConfig({
  hooks: {
    'pages:extend' (pages) {
      function setMiddleware(pages) {
        for (const page of pages) {
          if (page.path.startsWith('/Investor')) {
            page.meta ||= {}
            page.meta.middleware = ['investor-auth']
          }
          // Add more conditions for other role-based paths
          
          if (page.children) {
            setMiddleware(page.children)
          }
        }
      }
      setMiddleware(pages)
    }
  }
})

This approach automatically applies the specified middleware to all pages in the Investor directory, including nested routes Docs > Guide > Directory Structure > Middleware.

Creating the role-based middleware

Then create your middleware file:

// middleware/investor-auth.ts
export default defineNuxtRouteMiddleware((to, from) => {
  // Get user role from your auth store
  const userRole = getUserRole() // implement this based on your auth system
  
  if (userRole === 'guest') {
    return navigateTo('/login')
  }
})

This approach ensures that all routes within the Investor directory are protected, regardless of how deeply nested they are.

Remember that middleware runs in a specific order: global middleware first, then page-defined middleware Docs > Guide > Directory Structure > Middleware.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@west cradle Kapa.ai is still learning and improving, please let me know how I did by reacting below.