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

twoarmtom's avatar

Mobile Menu not closing

I'm learning to use Inertia by rebuilding a previous project (love it so far). However, I've run into a strange issue that I understand why it's happening, but I'm embarrassed at my attempts to solve it. Basically, the mobile menu doesn't close after a link is clicked. I can't figure out how to close it in my Vue component. The part of the menu that is opening and closing is below, they are components imported from Headless UI.

<div class="-mr-2 flex md:hidden">
  <!-- Mobile menu button -->
  <DisclosureButton class="bg-gray-800 inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-white hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-white"> 
  <span class="sr-only">Open main menu</span>
  <MenuIcon v-if="!open" class="block h-6 w-6" aria-hidden="true" />
  <XIcon v-else class="block h-6 w-6" aria-hidden="true" />
  </DisclosureButton>
</div>

<DisclosurePanel class="md:hidden" id="mobile">
  <div class="px-2 pt-2 pb-3 space-y-1 sm:px-3">
   <BreezeNavLink class="block" :href="route('home')" :active="route().current('home')">
Competencies
   </BreezeNavLink>
   <BreezeNavLink class="block" :href="route('evaluations')" :active="route().current('evaluations')">
Evaluations
   </BreezeNavLink>
   <BreezeNavLink class="block" :href="route('formatives')" :active="route().current('formatives')">
Formatives
   </BreezeNavLink>
  </div>
  <div class="pt-4 pb-3 border-t border-gray-700">
   <div class="flex items-center px-5">
    <div>
     <div class="text-base pt-2 font-medium leading-none text-white">
      {{ user.name }}
     </div>
     <div class="text-sm py-1 font-medium leading-none text-gray-400">
     {{ user.email }}
     </div>
    </div>
    <button type="button"
class="ml-auto bg-gray-800 flex-shrink-0 p-1 rounded-full text-gray-400 hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-white">
    <span class="sr-only">View notifications</span>
    <BellIcon class="h-6 w-6" aria-hidden="true" />
    </button>
   </div>
   <div class="mt-3 px-2 space-y-1">
    <Link href="/"
class="block px-3 py-2 rounded-md text-base font-medium text-gray-400 hover:text-white hover:bg-gray-700">
    Account Info</Link>
    <Link href="/logout" method="post" as="button"
class="block px-3 py-2 rounded-md text-base font-medium text-gray-400 hover:text-white hover:bg-gray-700">
     Log Out
    </Link>
   </div>
  </div>
</DisclosurePanel>

The DisclosureButton opens the DiscloserPanel. These are imported from Headless UI, I don't have any functions in my component related to these elements. The BreezeNavLink is borrowed classes are customized from a Breeze include.

Here are all of the sections.

<script>
import { Disclosure, DisclosureButton, DisclosurePanel, Menu, MenuButton, MenuItem, MenuItems } from '@headlessui/vue'
import { BellIcon, MenuIcon, XIcon } from '@heroicons/vue/outline'
import { Link } from '@inertiajs/inertia-vue3'
import BreezeDropdownLink from '@/Components/DropdownLink.vue'
import BreezeNavLink from '@/Components/NavLink.vue'

export default {
    components: {
    Link,
    BreezeNavLink,
    Disclosure,
    DisclosureButton,
    DisclosurePanel,
    Menu,
    MenuButton,
    MenuItem,
    MenuItems,
    BellIcon,
    MenuIcon,
    XIcon,
    BreezeDropdownLink,
  },
  computed: {
    user() {
      return this.$page.props.auth.user;
    },
  },
}
</script>

I've tried an @click method (function) to close the this.DisclosurePanel, but that didn't work and felt like a rather amateur attempt. Can anyone suggest an easy way to get it to close in between Inertia rendered pages?

Thanks for considering.

0 likes
1 reply
twoarmtom's avatar

I was able to create a solution. If anyone thinks there might be an issue with it please let me know.

I added the following setup function found in their documentation (without a fetch request).

setup() {
      return {
        closeMenu: async (close) => {
          close()
        },
      }
    },

Then I added @click="closeMenu(close) to the links and v-slot="{ close }" to the panel.

<DisclosurePanel class="md:hidden" v-slot="{ close }">
  <div class="px-2 pt-2 pb-3 space-y-1 sm:px-3">
    <BreezeNavLink class="block" :href="route('home')" :active="route().current('home')" @click="closeMenu(close)">
                    Competencies
      </BreezeNavLink>...

Please or to participate in this conversation.