Brand
A compact logo + name combo for the leading slot of a <x-wirekit:: or a sidebar. Brand renders an <a> element that doubles as the "home" link of your app — click the logo to return to / (or a custom href).
Basic Usage
Pass name for a text-only brand, logo for an image-only brand, or both for a combined mark. The logo image is decorative (alt="", aria-hidden="true"); the accessible name of the link comes from name when present.
Custom Link Target
By default the brand links to /. Use href="…" to point it elsewhere (landing page, marketing site, app root in multi-root setups).
Inside a link
A mark sometimes sits inside something that is already a link: the brand of an
app rail with an href, or a header's own home link.
There a brand with a link of its own would put a link inside a link. Pass :href="false" and the
brand renders a plain <span>: no link, no name of its own, only the mark and whatever else you
put in it. The images stay decorative, so the link around it keeps the name.
{{-- 1. The rail's brand is the link home and carries the name. --}}
<x-wirekit::app-rail.brand href="/" name="Acme Industries">
{{-- 2. The marks inside it have no link of their own. --}}
<x-wirekit::brand :href="false" logo="/brand/signet.svg" dark-logo="/brand/signet-dark.svg" logo-aspect="1/1" size="xs" />
</x-wirekit::app-rail.brand>
It has to be false (or an empty string), not null: Blade gives a prop passed as null its
default, and the default is /.
Sizes
size sets the height of the logo, on the same scale as the avatar:
xs, sm (the default), md and lg, 1.5 to 3rem. The width follows from the image, or from
logo-aspect when you give one.
When the logo has to match a height the scale does not have, give size a CSS length instead,
such as 1.75rem for a 28px row. It takes a number with rem, em or px, and anything else
is reported like a size off the scale, through strict validation.
A Long Name in a Narrow Bar
A brand keeps the width of its name by default, so in the middle of a shell bar on a phone a long product name pushes the rest of the row aside. Add truncate and the brand gives way instead: the name ends in an ellipsis, and the logo keeps its size.
{{-- 1. The name shortens with an ellipsis; the logo stays whole. --}}
<x-wirekit::shell-bar>
<x-wirekit::brand logo="/images/logo.svg" logo-aspect="1/1" name="Acme Industries Operations Console" truncate />
</x-wirekit::shell-bar>
Without truncate the brand keeps its full width and never shortens the name.
Custom Content
If you need more than a logo and name (e.g. a workspace switcher chevron, a product badge), pass arbitrary children. They render after the logo and the name rather than replacing either, so a brand can carry all three.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
logo |
string|null |
null |
URL of the canonical wide-form logo image. Rendered at the height size names, w-auto. Decorative — alt="", aria-hidden="true". |
mobileLogo |
string|null |
null |
Optional URL of a compact mobile variant (square mark, monogram, icon-only). When set together with logo, the component renders TWO <img> tags with a Tailwind responsive swap — mobile shows the compact variant, wider viewports show the canonical logo. When unset, behavior is unchanged. |
mobileBreakpoint |
'sm'|'md'|'lg'|'xl' |
'sm' |
The Tailwind breakpoint at which the responsive swap flips from mobileLogo to logo. Default sm (640 px) — wide wordmarks typically clear sm+ viewports. No-op when mobileLogo is null. An invalid value is reported through strict validation and falls back to sm. |
darkLogo |
string|null |
null |
Optional URL of a dark-mode logo variant. When set with logo, the component renders a light/dark <img> pair that swaps automatically under the .dark class (via the wk-light-only / wk-dark-only visibility classes — never a dark: utility). Composes with mobileLogo: the mobile mark stays mode-neutral, the light/dark swap applies to the desktop logo. When unset, behavior is unchanged. |
logoAspect |
string|null |
null |
Intrinsic aspect ratio of logo / darkLogo as 'width/height' — e.g. '4/1' for a wide wordmark. Every logo here has a fixed height and w-auto, so the width comes from the image; until its bytes arrive there is nothing to derive it from and the header shifts when it loads. Declaring the ratio reserves the space. Unset is not left to shift — the images carry a min-width of one logo height, so the worst case is a square reservation rather than nothing |
mobileLogoAspect |
string|null |
null |
Same, for mobileLogo. Defaults to logoAspect; give it its own value when the mobile mark is a different shape — a square app icon beside a wide wordmark is exactly that case |
logoLoading |
'eager'|'lazy' |
'eager' |
How the browser fetches the logo images. A mark is almost always above the fold, so it loads eagerly; pass 'lazy' for one further down the page, such as a footer. Every logo image also carries decoding="async", which keeps decoding the mark off the path that paints the rest of the page. An invalid value is reported through strict validation and falls back to 'eager' |
name |
string|null |
null |
Brand name text. Rendered at --text-wk-lg with heading-weight font. |
href |
string|false |
'/' |
Link destination. :href="false" (or an empty string) renders no link at all, for a mark inside something that is already a link — see Inside a link |
size |
'xs' | 'sm' | 'md' | 'lg' | string |
'sm' |
Height of the logo: 1.5, 2, 2.5 or 3rem, the scale the avatar uses, or a CSS length such as '1.75rem' for a height between those steps. An invalid value is reported through strict validation |
truncate |
bool |
false |
Let the brand shrink in a narrow row: the name ends in an ellipsis and the logo keeps its size. See A Long Name in a Narrow Bar |
scope |
string|null |
null |
Named personalization scope for block-level class overrides. |
The default slot is additive, the same contract <x-wirekit:: has: it renders whether or not logo and name are set. With neither of them, it is the whole of the brand — pass your own markup for full control.
Responsive logo example
A wide wordmark on the home navbar overflows narrow viewports — mobileLogo swaps it for a compact mark below the chosen breakpoint:
At viewports below md (768 px) the compact mark renders; at md+ the full wordmark renders. Both share the same <a href>, so the click target is identical at every viewport.
Dark-mode logo
A wordmark tuned for a light header often disappears on a dark one. Set darkLogo to supply a second image that the component swaps in automatically under the .dark class — no dark: utilities, and no duplicate <x-wirekit:: elements toggled by hand:
The first image shows in light mode; toggle your app to dark mode and the darkLogo image takes over. darkLogo also composes with mobileLogo — the compact mobile mark stays mode-neutral below the breakpoint, and the light/dark swap applies to the desktop wordmark above it.
Accessibility
- Rendered as an
<a>element, so the brand is keyboard-focusable and reachable withTab. With:href="false"it is a plain<span>instead, with no name of its own: the link around it is what a keyboard or a screen reader reaches - The logo
<img>is decorative:alt=""andaria-hidden="true"so the accessible name comes from thenametext or the slot content - When
nameis omitted andlogois used alone, pass an explicitaria-labelon the component to give the link an accessible name:
<x-wirekit::brand
logo="/brand/mark.svg"
aria-label="Acme — back to dashboard"
/>
Without an accessible name, logo-only brands are unreadable by screen readers. The component does not enforce this — adding an aria-label is your responsibility.
Keyboard Interaction
The root is an <a href> — href defaults to / — so the brand IS in the tab order and Enter follows it. Pass :href="null" for a brand that is not a link, and it becomes presentational.
Design Tokens
| Token | Used for |
|---|---|
--color-wk-text |
Brand name color |
--gap-wk-sm |
Gap between logo and name |
--text-wk-lg |
Brand name font size |
--font-wk-heading-weight |
Brand name font weight |