How to Make Duda's Mega Menu Work on Click (Instead of Hover)
Kill the Hover, Embrace the Click: Fixing Duda's Mega Menu
Let me guess — you were cruising through Duda’s new Flex Editor, feeling pretty good about life, and then BAM — you added a Mega Menu, hovered your mouse over it, and that sucker exploded open like it had a caffeine addiction.
You thought, “Cool, now how do I make this open on click instead of hover?”
Spoiler alert: you can’t — at least not out of the box.
But don’t worry, I cracked the code and now I’m giving it to you. For free. Because I’ve already lost enough time (and brain cells) figuring this out so you don’t have to.

The Problem (a.k.a. Why You’re Crying in Flex Editor)
Duda’s Mega Menu works like this: you hover over a menu item, and it reveals a beautifully designed dropdown full of links, columns, images, or whatever other fancy stuff you packed in there.
Sounds great, right?
Well, sure — until you want to open it with a click instead. That’s when things get weird.
Here’s what was happening before I fixed it:
- The mega menu still opened on hover, even when I tried using custom code to stop it. It’s like Duda didn’t care what I wanted — it just did its own thing.
- When I tried to add a click trigger, it wouldn’t work on the first click. You’d have to click the menu item twice like it was playing hard to get.
- Sometimes the hover styles would sneak back in after page transitions or editor hydration. (Ghost styles, anyone?)
- And every now and then the menu would just flicker like a busted neon sign, making your site look like it was built in 2004.
Not exactly the premium UX your clients are paying for, right?
The Solution (Cue the Hero Music)
Instead of arm wrestling Duda’s internal menu system, I decided to go full ninja mode:
- I used event delegation to intercept clicks on mega menu links before Duda gets a chance to react.
- I grabbed the associated mega menu section by its ID, manually toggled its visibility, and completely nuked hover behavior.
- I made it work for multiple mega menus, because one just isn’t enough these days.
- And yes — it all works on the first click without cloning, replacing, or sacrificing a goat to the JavaScript gods.
The Code (That Will Save Your Sanity)
Copy and paste this into your Body End HTML in Duda Site Settings:
<script>
(function(){
const WRAP_ID = 'flex-mega-menu';
// hide every mega‐section
function closeAll(megaWrap) {
megaWrap
.querySelectorAll('[data-flex-id]')
.forEach(sec => {
sec.classList.remove('open');
sec.style.display = 'none';
});
}
function init() {
const navRoot = document.querySelector('nav[data-show-vertical-sub-items]');
const megaWrap = document.getElementById(WRAP_ID);
if (!navRoot !megaWrap) return false;
// disable hover‐on‐load
navRoot.setAttribute('data-show-vertical-sub-items','HIDE');
// hide panels immediately
closeAll(megaWrap);
// capture‐phase delegated click handler
document.addEventListener('click', e => {
const trigger = e.target.closest('[data-target-page-alias^="mega_menu:"]');
const clickedIn = e.target.closest(`#${WRAP_ID}`);
if (trigger) {
e.preventDefault();
e.stopPropagation();
// toggle exactly the one you clicked
closeAll(megaWrap);
const alias = trigger.getAttribute('data-target-page-alias');
const id = alias.split(':')[1];
const panel = megaWrap.querySelector(`[data-flex-id="${id}"]`);
if (panel) {
panel.classList.add('open');
panel.style.display = 'block';
}
return;
}
// click outside the mega → close all panels
if (!clickedIn) closeAll(megaWrap);
}, true);
return true;
}
// try immediately, otherwise watch for Duda to finish rendering
if (!init()) {
new MutationObserver((records, obs) => {
if (init()) obs.disconnect();
}).observe(document.body, { childList: true, subtree: true });
}
})();
</script>
Why It Works (And Why I’m So Damn Proud of It)
This approach is simple, scalable, and won’t break your editor experience. Here’s what makes it tick:
- Event delegation means we’re not attaching click handlers to each item directly. We’re catching clicks at the top and letting them bubble up.
- No cloning, replacing, or dark DOM rituals — just clean vanilla JavaScript.
- Hover behavior gets nuked right at the root with one simple
data-show-vertical-sub-items="HIDE"
. - It scales. Want 2 mega menus? 5? 47? This thing handles them all without breaking a sweat.
- It’s future-proof. Duda can update their internal logic all they want — we’re intercepting events before they get a chance to mess with them.
Final Thoughts
Let’s be real: Duda’s Mega Menu is beautiful, but the default hover behavior isn’t for everyone. Especially when you're trying to build a clean, click-driven UX that works across devices and keeps users in control.
This fix gave me total control back — and now, you’ve got it too.
Want help implementing this?
