- header.ts now imports and re-exports functions from search.ts
and theme.ts for use in the header template
- Functions available via x-data=header:
- initializeSearch
- initializeTheme
- changeTheme
- changeWoodPaneling
- loadWoodPaneling
- updateWoodPanelingIndicators
- header.templ x-init calls these functions directly
- Enables proper SSR-first pattern with x-init for setup only
- Add defer attribute to <script src="/static/main.js"> in 21 template files
- Improves page load performance by allowing HTML parsing to continue without blocking
- Maintains script execution order while enabling parallel resource loading
- Remove duplicate defer attribute from header.templ line 264
- Add websocket.ts import to main.ts for module registration
This optimization reduces page render blocking and improves perceived load times
by allowing the browser to continue parsing HTML while the main.js bundle loads.
The defer attribute ensures scripts execute in order after HTML parsing completes.
Affected templates include:
- Admin pages: admin, admin_library, admin_settings, admin_users
- Content pages: analytics, bookshelf, collections, conflicts, custom_section
- User pages: dashboard, devices, docs, index, login, profile, progress, queue, register
- System pages: header, unlinked_books
- Add defer attribute to all main.js script includes across 22 template files
- Improves page load performance by allowing HTML parsing to continue without blocking
- Maintains script execution order while enabling parallel resource loading
This optimization reduces page render blocking and improves perceived load times
across all admin and user-facing pages that include the main.js bundle.
Affected pages include: admin dashboard, library management, settings, user
management, analytics, bookshelf, collections, conflicts, custom sections,
devices, documentation, profile, progress tracking, queue, and authentication
pages (login/register).
This commit updates all generated template files and the header.templ source
to use consolidated script bundles and modern Alpine.js syntax.
Changes to templates/*.go (generated from .templ source files):
- Replace individual script imports (admin.js, toast.js, header.js, etc.)
with single /static/main.js bundle
- Convert onclick attributes to Alpine.js @click directives for better
integration with reactive components
- Add x-data attributes to body elements where needed for Alpine components
- Update event handlers to use Alpine.js syntax consistently
Changes to templates/header.templ source file:
- Add Alpine.js test div with x-data and x-init for debugging
- Reformat theme dropdown and user menu markup with proper indentation
- Maintain consistent Alpine.js directive formatting throughout
This change reduces the number of HTTP requests and ensures consistent
Alpine.js integration across all pages.
Migrated header template from hybrid onclick/@click with manual DOM
manipulation to full reactive Alpine.js with state-driven UI.
Template Changes (templates/header.templ):
- Added x-data state container: { themeDropdownOpen, userMenuOpen }
- Replaced @click="toggleThemeDropdown()" with @click="themeDropdownOpen = !themeDropdownOpen"
- Replaced id/class="hidden" with x-show directives
- Added @click.outside for click-outside-to-close behavior
- Added x-transition for smooth dropdown animations
- Added inline style="display: none;" to prevent FOUC
- Updated theme buttons to use header.changeThemeTo() namespace
- Updated wood paneling buttons to use woodPaneling.change() namespace
- Updated logout to use header.logout() namespace
- Close dropdowns after action: themeDropdownOpen = false
TypeScript Changes (web/src/header.ts):
- Removed toggleThemeDropdown() function (lines 7-18) - no longer needed
- Removed toggleUserMenu() function (lines 20-31) - no longer needed
- Removed manual DOM manipulation from changeThemeTo() (lines 50-54)
- Removed click-outside event listener (lines 64-88) - Alpine handles this
- Updated export to remove deleted functions
- Updated Alpine.global() registration to remove toggle functions
- Result: header.ts reduced from 100 lines to 40 lines (60% reduction)
TypeScript Changes (web/src/woodPaneling.ts):
- Added Alpine import
- Removed manual DOM manipulation from changeWoodPaneling()
- Added Alpine.global("woodPaneling", { change: changeWoodPaneling })
TypeScript Changes (web/src/themeDropdown.ts):
- Removed import of deleted toggleThemeDropdown function
- Removed initializeThemeDropdown() wrapper function
- Removed initializeChangeThemeTo() wrapper function
- Simplified updateThemeIndicators() to focus on wood paneling
- Updated Alpine.global("themeDropdown") registration
Benefits:
- Eliminates 23 manual DOM manipulations from header
- Smooth transitions with x-transition
- Click-outside behavior built-in with @click.outside
- State is local and encapsulated in template
- Cleaner separation of concerns (UI state in template, business logic in TS)
- Easier debugging with Alpine DevTools
Testing:
- Theme dropdown opens with smooth transition
- Theme dropdown closes when clicking outside
- Theme changes correctly when option clicked
- User menu opens with smooth transition
- User menu closes when clicking outside
- Logout works correctly
- Wood paneling changes work
- Both dropdowns show mutual exclusion behavior
Build Verification:
- templ generate: ✓ Success
- npm run build:ts: ✓ Success (167.8kb minified)
This is the reference implementation for Phase 1 of the Alpine.js
integration completion guide. All other modal templates should
follow this same pattern.
Related: ALPINE_COMPLETION_GUIDE.md Phase 1
Related: ESBUILD_MIGRATION_PLAN.md Phase 3, Template Migration
- Update header.templ to load single main.js script instead of 4 separate files
- Remove obsolete header.js and search.js as they are now bundled
- Update Alpine.js event handlers to use standard double quotes
- This completes the ESBuild migration by eliminating inline script loads
The main.js bundle now contains all header, theme, and search functionality
previously loaded separately, improving load performance and maintainability.
- Add theme.js script include to header template
- Fixes theme selector not working on pages using Header component
- Ensures applyTheme() is defined before changeThemeTo() calls it
Add admin_users.templ for user management interface with delete, password
reset, and edit capabilities. Add profile.templ and related components for
user profile management. Remove admin_profile.templ. Update all templates
to use new consolidated API endpoints.
- Move header.js script from individual templates to header.templ
- Removes duplicate script tags from bookshelf, collections, progress, etc.
- Fixes indentation in docs.templ
- Update header navigation to link to /dashboard instead of /bookshelf
- Update index page auto-redirect to use /dashboard
- Remove duplicate route, keeping full-featured dashboard with filters
Template changes:
- Update page titles: "Bookmann" → "Bookhoard"
- Update header branding and navigation text
- Regenerate compiled .go templates from .templ sources
- Update all UI references in HTML templates
This is part 3 of the project rename to Bookhoard.
Add navigation menu in header to make Phase 9 features discoverable:
- Library: Main bookshelf view
- Collections: Collection management interface
- Progress: Reading progress visualization across devices
- Devices: Device management and configuration
Navigation is hidden on mobile (responsive design) and visible on
larger screens (md breakpoint and above). This improves UX by
providing clear access to all major features.
- Create search.js with debounced input (300ms)
- Display results in dropdown modal with highlighted matches
- Support keyboard navigation (arrows, Enter, Escape)
- Show result count and 'no results' state
- Highlight matching terms in results
- Add autocomplete attribute to search input
- Minimum 2 characters to trigger search
- Add header.templ component with app title, search, theme switcher, user menu
- Implement dropdown menus for theme selection and user actions
- Add wood theme options (Wood Light, Wood Dark, Wood Mahogany)
- Support all existing themes with visual color swatches
- Auto-close dropdowns when clicking outside
- TypeScript header functionality with proper type safety
Features:
- Left: App title "📚 Bookmann" linking to /bookshelf
- Center: Search box (ready for future search functionality)
- Right: Theme switcher button with color dropdown → User icon menu
- User menu includes Settings, Admin Panel (if admin), and Logout
- Theme persistence to localStorage and server via API