Preline Collapse Menu Setup

User
<script>
import { ref, onMounted } from 'vue';
import { Link,usePage } from '@inertiajs/vue3';
import LanguageSwitcher from '@/Components/LanguageSwitcher.vue';
</script>

Sign in

Hire us

Work

Services

About

Careers

Blog

About

Services

Blog

collapse not worked

Assistant
To make the mobile **collapse menu (hamburger menu)** work, you need a JavaScript plugin or logic to toggle the menu. Your HTML uses attributes like `data-hs-collapse` and `hs-collapse-toggle`, which are specific to the **[Preline UI library](https://preline.co/)**.

So, here are the **steps to make collapse work**:

### ✅ 1. **Install Preline**
Preline is required for the collapse to function. Install it via npm or yarn:

npm install preline
# OR
yarn add preline

### ✅ 2. **Initialize Preline in `main.js` or `main.ts`**
Update your Vue entry file (likely `resources/js/app.js` or `main.js`) to initialize Preline:

import 'preline';

And if you're using Vite and need it to re-apply on page changes with Inertia.js, do this after every visit:

import { createApp, h } from 'vue'
import { createInertiaApp } from '@inertiajs/vue3'
import 'preline'

createInertiaApp({
  // ...
  setup({ el, App, props, plugin }) {
    const app = createApp({ render: () => h(App, props) })
    app.use(plugin).mount(el)

    // Reinitialize Preline components on each Inertia navigation
    import('preline').then(() => {
      window.HSStaticMethods?.autoInit?.();
    });
  },
})

### ✅ 3. **Make Sure IDs Match**
You already have this, but just to confirm:

<button
  data-hs-collapse="#hs-navbar-hcail"
  id="hs-navbar-hcail-collapse"
>
...
</button>

<div id="hs-navbar-hcail" class="hs-collapse hidden ...">
...
</div>

This is correct, as long as Preline is initialized.

### 🔁 Optional: Re-initialize on Inertia Navigate
If you notice it only works on first page load and breaks on route change (Inertia), you can use a `watch` or `onMounted` inside your `Layout.vue`:

<script setup>
import { onMounted } from 'vue';
import { router } from '@inertiajs/vue3';

onMounted(() => {
  window.HSStaticMethods?.autoInit?.();
});

router.on('navigate', () => {
  setTimeout(() => {
    window.HSStaticMethods?.autoInit?.();
  }, 50); // small delay for DOM to update
});
</script>

Let me know if you're not using Preline or want to use a custom Vue logic instead — I can guide you through that as well!

User
In vue
Assistant
Perfect! Since you’re working in Vue and want the **mobile collapse menu** to function properly (and you're using the Preline UI framework), you’ll need to ensure Preline is initialized **on mount** and **on route changes** using Vue's lifecycle hooks.

Here’s how to do it **in a Vue + Inertia + Preline setup**:

### ✅ Step-by-Step Vue Setup for Preline Collapse

### 1. **Install Preline**

If you haven't yet:

npm install preline

### 2. **Import & Initialize Preline in `app.js` or `main.js`**

If you're using `resources/js/app.js`, add this:

import { createApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/vue3';
import 'preline'; // Import Preline styles & scripts

createInertiaApp({
  resolve: name => require(`./Pages/${name}.vue`),
  setup({ el, App, props, plugin }) {
    const app = createApp({ render: () => h(App, props) });
    app.use(plugin);

    app.mixin({
      mounted() {
        // Re-init Preline when component is mounted
        window.HSStaticMethods?.autoInit?.();
      },
    });

    app.mount(el);

    // Optional: re-init on Inertia navigation
    import('@inertiajs/core').then(({ router }) => {
      router.on('navigate', () => {
        setTimeout(() => {
          window.HSStaticMethods?.autoInit?.();
        }, 10);
      });
    });
  },
});

### 3. **Ensure Collapse Markup is Correct**

You already have:

<!-- Button -->
<button
  type="button"
  class="hs-collapse-toggle ..."
  data-hs-collapse="#hs-navbar-hcail"
>
  <!-- Icon SVGs -->
</button>

<!-- Collapsible Menu -->
<div
  id="hs-navbar-hcail"
  class="hs-collapse hidden ..."
>
  <!-- menu content -->
</div>

✅ This is correct. As long as Preline’s JS is initialized, this will work.

### ✅ Alternate: Manual Reinit in Layout.vue

If you're doing this inside a Vue layout or component like `AppLayout.vue`, you can manually trigger `autoInit` using `onMounted`:

<script setup>
import { onMounted } from 'vue';

onMounted(() => {
  window.HSStaticMethods?.autoInit?.();
});
</script>

### ✅ Bonus: Ensure Preline CSS is Available

Make sure Tailwind is configured and you're importing styles either via:

import 'preline/preline.css';

or in your `app.css`:

@import 'preline/preline.css';

### 🧪 Test It Out

Once you do this, go to mobile view → click hamburger menu → collapse should toggle in/out.

Let me know if you want to ditch Preline and use Vue’s `ref()` and custom collapse logic instead!

Assistant
You want the hamburger menu toggle to work **without any external library** right?

I'll make a simple Vue solution to toggle the mobile menu.

Before I proceed, confirm:

✅ Using Vue 3
✅ No jQuery or Preline
✅ Just simple Vue `v-if` / `v-show` toggle

Should I implement it like this?

User
Yes
Assistant
Perfect! Here's a clean **Vue 3 way** to make your mobile navbar collapse work using `ref` and `v-show`.

### ✅ Step 1: Add reactive state

In your “ section, add a `ref` to manage toggle:

<script setup>
import { ref } from 'vue';

const isNavOpen = ref(false);
</script>

### ✅ Step 2: Update the toggle button

Replace your toggle button logic like this:

<button
  type="button"
  @click="isNavOpen = !isNavOpen"
  class="size-9.5 flex justify-center items-center text-sm font-semibold rounded-xl border border-gray-200 text-black hover:bg-gray-100 focus:outline-hidden focus:bg-gray-100 disabled:opacity-50 disabled:pointer-events-none dark:text-white dark:border-neutral-700 dark:hover:bg-neutral-700 dark:focus:bg-neutral-700"
  aria-label="Toggle navigation"
>
  <svg v-if="!isNavOpen" class="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
    <line x1="3" x2="21" y1="6" y2="6" />
    <line x1="3" x2="21" y1="12" y2="12" />
    <line x1="3" x2="21" y1="18" y2="18" />
  </svg>
  <svg v-else class="shrink-0 size-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
    <path d="M6 18L18 6M6 6l12 12" />
  </svg>
</button>

### ✅ Step 3: Toggle the menu visibility

Replace the menu collapse div like this:

<div
  v-show="isNavOpen"
  class="overflow-hidden transition-all duration-300 basis-full grow lg:block lg:w-auto lg:basis-auto lg:order-2 lg:col-span-6"
>
  <!-- Your nav links -->
</div>

> 🔁 If you want smooth transitions, you can enhance this with `v-if` and `v-transition` later — let me know if you want that too.

### ✅ Done!

This will make your navbar collapse show/hide responsively using Vue only — no extra libraries needed.

Let me know if you'd like:

– transition effects,
– closing the menu on link click,
– or toggling based on screen size.

I'm happy to help!

Leave a Comment

Your email address will not be published. Required fields are marked *