Skip to content
Twilight React Playground
ثيم رائدaren

Header

componentBeginnerserverbrowser

The storefront header: top bar with search and language, logo, main menu, account and cart, built from the store's data.

import { Header } from '@salla.sa/twilight-theme-engine/components/layout';

In plain words

The header is the top of every page: an announcement strip, a top bar with the search box and the language switch, then the logo, the main menu, the account button and the cart icon. Header renders all of it from the store's own data, and MasterLayout puts it on every page for you.

You render it yourself only when you build a layout of your own. See it live, at phone, tablet and desktop widths, in Built-in pages.

Signature

const Header: LazyExoticComponent<(props: HeaderProps) => JSX.Element>

// HeaderProps is not exported
interface HeaderProps {
  cart?: Cart;   // accepted and ignored
}

Example

app/components/ThemeLayout.tsx
import { Suspense } from 'react';
import { Footer, Header, type LayoutProps } from '@salla.sa/twilight-theme-engine/components/layout';
import { TrustBar } from './TrustBar';

// Passed to TwilightProvider as layout={ThemeLayout}, replacing MasterLayout.
export function ThemeLayout({ children }: LayoutProps) {
  return (
    <div className="app-inner flex flex-col min-h-full">
      <Suspense fallback={null}>
        <Header />
      </Suspense>
      <TrustBar />
      <main id="main-content" className="flex-1">
        {children}
      </main>
      <Suspense fallback={null}>
        <Footer />
      </Suspense>
    </div>
  );
}

How it behaves

  • Top to bottom: the header:start hook slot; the advertisement bar; the top bar (the footer menu when the theme setting important_links is on, a language and currency button when the store is multilingual or has several currencies, a branch button when the store has a scope, the search box, contact links); the main bar (mobile menu button, logo, main menu, account menu, cart summary); the mobile menu; the header:end hook slot.

  • Theme settings it reads: topnav_is_dark (a dark top bar), important_links, and header_is_sticky (the main bar gets sticky top-0).

  • The logo is an Image with priority, width 120 and height 48. The store name sits beside it for screen readers only, as an <h1> on the home page and a <span> elsewhere.

  • The language button calls window.Salla.event.dispatch('localization::open'); the search box, menus, account menu and cart summary are Salla web components.

  • The main menu and the mobile menu are internal: there is no export to reuse them on their own.

  • It is lazy (code-split).

Gotchas

  • The logo is a plain <a href={store.url}>, and store.url is the store's Salla address. On a merchant's own domain the link interceptor turns that click into a client-side navigation, but on localhost and the preview host the address is another site (https://demostore.salla.sa/ar/dev-…/), so clicking the logo leaves your preview.

  • A layout built from Header and Footer, like the example, loses what MasterLayout renders beside them: the login modal for guests, the offer pop-up and the branch picker. Render those too, or keep MasterLayout and add content through the header:start and header:end slots.

  • cart is accepted and ignored: the cart icon is a Salla web component that reads the cart from the SDK.

Related

Source and docs