CustomerLayout
The account area's frame: a breadcrumb band, the account menu sidebar and the page title around each account page.
import { CustomerLayout } from '@salla.sa/twilight-theme-engine/components/layout';In plain words
The customer's account area (orders, wishlist, wallet, profile) has a frame of its own inside the store's frame: a coloured band with breadcrumbs, a side menu of the account pages, and the page title above the content. CustomerLayout is that frame, and the engine's generated account route already puts every account page inside it.
Signature
const CustomerLayout: LazyExoticComponent<(props: CustomerLayoutProps) => JSX.Element>
// CustomerLayoutProps is not exported
interface CustomerLayoutProps {
children: ReactNode;
page?: Page; // the account page's loader data: title, slug, breadcrumbs
}Example
import { useMemo } from 'react';
import { CustomerLayout } from '@salla.sa/twilight-theme-engine/components/layout';
import { useTranslation } from '@salla.sa/twilight-theme-engine/i18n';
import type { Page } from '@salla.sa/twilight-theme-engine/types';
import { ReturnsList } from './ReturnsList';
// A page of your own that sits in the account frame, like the engine's account pages.
export function ReturnsPage() {
const { t } = useTranslation();
const page = useMemo<Page>(
() => ({
title: t('pages.returns.title', 'Returns'),
slug: 'returns',
breadcrumbs: [
{ name: t('common.titles.home'), url: '/' },
{ name: t('pages.returns.title', 'Returns'), url: '/returns' },
],
}),
[t]
);
return (
<CustomerLayout page={page}>
<ReturnsList />
</CustomerLayout>
);
}
How it behaves
Layout: a
profile-header gradient-bgband withBreadcrumbwhenpageis given; a sidebar with Salla's inline user menu (wide screens only) and, on the profile page, an avatar upload; then the content column withpage.titleas an<h1>above the children.The engine's account layout route renders it around every
/account/…page, withpagetaken from the deepest matched route's loader data. That route file is generated inside the engine package (.twilight/account.tsx), not in yourapp/routes, so a theme cannot edit it. Its loading state isCustomerLayoutSkeleton, unless a component is registered underaccount:layout-pending.It renders inside the store frame (
MasterLayout), not instead of it.Account pages need a logged-in customer, so Built-in pages sends a guest to log in rather than showing it.
It is lazy (code-split).
Gotchas
The avatar upload appears only when
page.slugis exactlyprofile, the slug the engine's profile loader sets. A profile page of your own with another slug gets no avatar upload.
Related
Draws a page's breadcrumb trail from its loader data, with structured data for search engines, unless the merchant turned breadcrumbs off.
Page skeletonsLoading placeholders shaped like the home, product, cart, blog and account pages, shown while the next page loads its data.
useUserThe logged-in customer as a TanStack Query result, plus an isLoggedIn flag; it never requests anything for guests.