Header and Footer Presets, SCSS and Theme Assets

How Echo's header and footer are put together, why menus fit without JavaScript, how the Sass is organised, and where built and static assets come from. Read this before you override header or footer views or add CSS.

Header presets

The header layout is the header_preset theme option. Each preset is one Blade file in resources/themes/echo/components/headers/, chosen by components/application-header.blade.php.

IdLayout
logo-leftClassic: logo left, navigation right (default)
centeredLogo on top, navigation below; optional search
splitNavigation split around a centred logo
pillFloating, rounded, detached bar
fullscreenMinimal bar with a full-screen overlay menu
commerceSearch-first, two tiers
contactContact details card and a call to action
tagLogo on a tab hanging below the bar
indexNumbered, ruled navigation cells

Old ids stored in sites' options and page settings are mapped to current ones in application-header.blade.php (centered-split → split, offcanvas → fullscreen, utility-bar → contact, transparent-overlay → logo-left). Keep that map when you rename or remove a preset.

The right-hand cluster

Every preset renders components/headers/partials/actions.blade.php: an account icon, a cart icon, then one filled call-to-action button (header_cta_label, header_cta_url), then the drawer button when the menu does not fit.

How a menu decides whether it fits

No JavaScript measures the menu. When a menu's cache is built, Menu::fitBucket() turns the top-level labels into a weight from 1 to Menu::FIT_OVERFLOW (characters, plus extra for each item, caret and icon). The header prints it as data-nav-fit, and _header.scss generates, per preset, the screen width at which a menu of that weight fits beside the logo and the action cluster. Below that width the drawer button shows; above FIT_OVERFLOW the menu always lives in the drawer.

Top bar

The optional top bar (topbar_enabled) has a start and an end side. Each side is either text or a menu (topbar_start_type, topbar_end_type), never widgets. Text passes through TopbarHtml::clean(), which keeps only i, span, strong, b and a, before it is printed unescaped; menus render top-level items only through menu/topbar.blade.php.

Echo's Sass

resources/themes/echo/assets/sass/
  app.scss            entry: Bootstrap with Echo's variables, then Echo's layers below
  app-editor.scss     a scoped copy for the page-builder canvas
  _variables.scss     Bootstrap variable overrides (Echo's spacer scale is custom)
  global.scss, _mixin.scss, _animations.scss, _dark-mode.scss, _rtl.scss
  components/         header, footer, nav, buttons, forms, widgets, publication (blog), page sections ...
  layout/ pages/ utilities/ widgets/
  kit/                the ui-* section kit used by template-library layouts

Building assets

All front-end code is built by one Vite configuration at the project root. Every entry point, including those of bundled modules, is listed in its input array:

EntryLoaded by
resources/themes/echo/assets/sass/app.scss, app-editor.scss, assets/js/app.jsEcho layouts; the editor canvas
resources/themes/admin/assets/sass/app.scss, assets/js/app.js, page-builder.js, GrapesJS stylesAdmin layout and page builder
resources/themes/echo/page-templates/scripts/motion.js, widgets.jsOnly pages that contain a section needing them
Modules/{Booking,TruCommerce,TruPayments}/resources/...Each module's admin and front layouts, via @vite()
npm run build            # production build into public/build
npm run dev              # dev server with hot reload
npm run templates:kit    # rebuild the ui-* section kit CSS stored for the template library

After a build that changes Echo's styles, regenerate the theme CSS (see How options become CSS). The full build reference, including how a plugin ships its own assets, is in Build and assets.

Static assets