Account
The shared /account layout that frames every signed-in page, and how a child page shapes it.
Framework: TanStack Start
This page is written for TanStack Start, the default and currently supported framework. See what depends on the framework.
Every signed-in page (profile, orders, wallet and the rest) shows inside one frame: a breadcrumb, a title, and a user menu on large screens. That frame is the /account layout. Read this page when you want to retitle a page in the frame, show your own skeleton while it loads, or style account pages differently from the rest of the store.
URL
/account is a layout route: it has no page of its own. It wraps whichever child page matches.
| URL | Renders |
|---|---|
/account | the frame with an empty body, because no child matches |
/account/profile, /ar/account/profile | the frame around Profile |
The children are profile, wishlist, wallet, notifications, settings, orders and one order. Pending orders is also nested here, but it only redirects.
The only param is the optional locale ({-$locale}). See Languages and RTL.
Route file
There is no app/routes/account.tsx in your project. The engine registers the layout itself, so you cannot take it over by copying a file. What it does is simple: it reads page from the deepest child's loader data and hands it to CustomerLayout, with the child inside.
Shape the frame from a child route
The frame takes its title and breadcrumb from the child's page ({ title, slug }). To change them, return a new page from the loader's extend argument:
import { createFileRoute } from '@tanstack/react-router';
import { Profile } from '@salla.sa/twilight-theme-engine/routes/account';
import type { ProfilePageProps } from '@salla.sa/twilight-theme-engine/routes/account';
import { CustomerPageSkeleton } from '@salla.sa/twilight-theme-engine/skeleton';
import { withHead } from '@salla.sa/twilight-theme-engine/tanstack';
export const Route = createFileRoute('/{-$locale}/account/profile')({
loader: ({ params }): Promise<ProfilePageProps> =>
Profile.loader({ locale: params.locale }, (data) => ({
page: { ...data.page, title: 'My details' },
})),
head: withHead(Profile),
pendingComponent: () => <CustomerPageSkeleton />,
component: function ProfileRoute() {
const data: ProfilePageProps = Route.useLoaderData();
return <Profile.Component {...data} />;
},
});What the layout provides
- The breadcrumb and
<h1>, from the child'spage. The profile page also gets the avatar uploader above the menu. - A
customerclass on<body>, so you can scope styles to account pages. - The user menu sidebar, on large screens only.
- A skeleton while a child loads:
CustomerLayoutSkeleton, or your own component registered under the keyaccount:layout-pending.
What it loads
Nothing. Each child loads its own data and decides whether a token is needed. The layout does not redirect a signed-out customer and sets no head tags; each child sets its own title and language alternates.
Edge cases
/accounton its own shows the frame with an empty body and no title. Link to a child page, such as/account/orders.- Signed out. Handled per child: each throws
unauthorized(), which sends a guest to the home page with?intended_to=, where the Salla SDK opens the sign-in form. See Authentication and scope.
See also
- Account profile, the first child page
- Fork a built-in route and Loading data
- Overview of every route