Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

DevIP98's avatar

Submenu Laravel Starter Kit

how can I add a submenu in the Laravel Starter Kit template of laravel 12?

AppSidebar.vue

const mainNavItems: NavItem[] = [
    {
        title: 'Dashboard',
        href: '/dashboard',
        icon: LayoutGrid,
    },
    {
        title: 'Usuarios',
        href: route('users.index'),
        icon: Users,
    },
];
0 likes
3 replies
DevIP98's avatar

I did it, I did this.

Interface and Navigation Modifications

Step 1: Modification of the NavItem Interface

Modified file: c:\sistemas\aseosoft\resources\js\types\index.ts

Added the property children?: NavItem[] to the NavItem interface. This allows each navigation item to have child elements (submenus).


Step 2: Creation of the SidebarSubMenu Component

Created file: c:\sistemas\aseosoft\resources\js\components\ui\sidebar\SidebarSubMenu.vue

Created this new component to display submenu items. The component has an indented style and a vertical line on the left to indicate hierarchy.

Added Code:

<script setup lang="ts">
import { cn } from '@/lib/utils';

defineProps<{ className?: string }>();
</script>

<template>
  <div :class="cn('ml-4 pl-4 border-l space-y-1', className)">
    <slot />
  </div>
</template>

Step 3: Update of the Component Export File

Modified file: c:\sistemas\aseosoft\resources\js\components\ui\sidebar\index.ts

Added the export of the new SidebarSubMenu component so it can be imported from other files.

Added Line:

export { default as SidebarSubMenu } from './SidebarSubMenu.vue';

Step 4: Modification of the NavMain Component

Modified file: c:\sistemas\aseosoft\resources\js\components\NavMain.vue

Changes Made:

  • Imported the SidebarSubMenu component and the ChevronDown icon.
  • Created a reactive state openSubMenus to control which submenus are open.
  • Implemented toggleSubMenu function to show/hide submenus.
  • Implemented isCurrentRoute function to detect active routes, including nested ones.
  • Added conditional logic in the template to display regular items or items with submenus.
  • Added animation for the arrow icon when opening/closing a submenu.

Step 5: Update of the AppSidebar Component

Modified file: c:\sistemas\aseosoft\resources\js\components\AppSidebar.vue

Changes Made:

  • Added new icons: UserPlus and UserCog for submenu items.
  • Modified the "Users" navigation item to include child elements.

Added Code:

{
    title: 'Users',
    href: route('users.index'),
    icon: Users,
    children: [
        {
            title: 'User List',
            href: route('users.index'),
            icon: Users,
        },
        {
            title: 'Create User',
            href: route('users.create'),
            icon: UserPlus,
        },
        {
            title: 'Roles and Permissions',
            href: '/users/roles',
            icon: UserCog,
        },
    ],
}
Jboomer's avatar

@devip98 do you have acopy of your code i'm trying to implement the same thing and running into a little hiccup.

PatrickCaneloDigital's avatar

There is a very very simple approach with a few changes, and a more sophisticated one (laravel 12 as reference).

a) THE QUICK WAY

a1) edit: resources/types/navigation.ts:

add children as attribute recursive to NavItem

export type NavItem = {
title: string;
href: NonNullable<InertiaLinkProps['href']>;
    icon?: LucideIcon;
    isActive?: boolean;
    children?: NavItem[];
};

a2) edit NavMain.vue

AFTER the closing SidebarMenuButton but still inside SidebarMenuItem add

<SidebarMenuItem
                    v-for="child in item.children"
                    :key="child.title"
                >
                    <SidebarMenuButton
                        as-child
                        :is-active="isCurrentUrl(child.href)"
                        :tooltip="child.title"
                    >
                        <Link :href="child.href">
                            &nbsp;&nbsp;&nbsp;- <span>{{ child.title }}</span>
                        </Link>
                    </SidebarMenuButton>
                </SidebarMenuItem>

b) THE LONG WAY

b1) is the same as a1, extend the definition of NavItem to be able to have children

b2) use DeviP98 definition for a SidebarSubMenu Component or in it's effect you can duplicate and edit SidebarMenuItem

b3) The same: you can duplicate SidebarMenuButton and create a SidebarSubmenuButton to your liking

b3) extend NavMain as described above, with an loop inside SidebarSubmenuItem on NavItem.children and use SidebarSubmenuItem and SidebarSubmenuButton

With both approaches the NavItem definition is infitely recursive and and with some clever coding you could make the SidebarMenuItem recursive too to adapt to infinite depth (create a component which takes navItems, loops through and when it come to children you refer recursive to that component and pass the childrenNavItems)

Please or to participate in this conversation.