The Alpine.js Component Override Bug
After merging the Focus Queue PR, the right-click context menu silently stopped working. No errors -- an inline script tag in a Blade template was overwriting the JS component.
After deploying the Focus Queue feature, right-clicking on tasks did nothing. No console errors, no exceptions -- just silence. The context menu HTML was rendering, but the component was broken.
The Clue
I added console.log('Context Menu initialized') to the component's init(). It never appeared. The method wasn't being called at all, which meant the component wasn't the one I thought it was.
The Cause
The contextMenu component was defined in two places:
// 1. In contextMenu.js (bundled by Vite)
Alpine.data('contextMenu', () => ({
hideMenu() { ... },
addToFocusQueue() { ... },
deleteItem() { ... },
}));
<!-- 2. In priority-context-menu.blade.php (inline script) -->
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('contextMenu', () => ({
close() { ... }, // Different method names!
openDetails() { ... },
deleteTask() { ... },
}));
});
</script>
The Blade template's inline script registered a different version of contextMenu that overwrote the JS file's version. Alpine uses the last-registered definition. The inline version had none of the methods the template was trying to call.
The Fix
Removed the 240-line inline script entirely. Updated the Blade template to use the JS file's method names:
{{-- Before --}}
<button @click="close">
<button @click="openDetails">
<button @click="deleteTask">
{{-- After --}}
<button @click="hideMenu">
<button @click="openTaskDetail(parseInt(targetItemId))">
<button @click="deleteItem">
The Rule
Never define the same Alpine.js component in multiple places. The load order -- Vite bundle first, then inline scripts via alpine:init -- means inline scripts silently win. No warning, no error, just a different component with different methods and silent failures everywhere.
Built while working on PlanPal.
Back to danielships ->