Preline Collapse Menu Setup
March 29, 2025 · AI Conversations
<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
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!
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!
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?
—
### ✅ 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!