FleetbaseFleetbase

Branding

Give the Storefront App your brand from one typed file — colors for light and dark, fonts, buttons, cards, tabs and home screen — plus your app icon and launch screen.

Branding

Everything about how a build looks lives in one typed, validated file, brand/storefront.brand.ts, with the brand's fonts, translations and artwork beside it in brand/. The app's own code stays untouched, so a branded build takes each new release as a plain merge. See Client Builds for the brand/ folder.

The store page in the dark appearance
Dark
The store page in the light appearance
Light
Checkout in the dark appearance
Dark
Checkout in the light appearance
Light

The brand file

// brand/storefront.brand.ts
import { defineBranding } from '../src/branding/define';

const body = { family: 'Golos Text', faces: { '400': 'GolosText-Regular', '600': 'GolosText-SemiBold', '700': 'GolosText-Bold' } } as const;

export default defineBranding({
    schemaVersion: 1,
    name: 'My Store',
    colors: {
        preset: 'orange',
        dark: { background: '#15171B', surface: '#1D2026', primary: '#F5821F', primaryText: '#15171B' },
        light: { background: '#F7F4EE', surface: '#EFEAE0', primary: '#C2410C', primaryText: '#FFFFFF' },
        extra: {
            dark: { gradientStart: '#E8482B', gradientEnd: '#F5821F' },
            light: { gradientStart: '#B8360F', gradientEnd: '#C2410C' },
        },
    },
    appearance: { defaultScheme: 'dark', allowUserToggle: true },
    typography: { body, heading: body },
    shape: { radius: { tile: 14, card: 16, sheet: 22 } },
    components: {
        productCard: { variant: 'outlined' },
        button: { fill: 'gradient', radius: 12 },
        chip: { selected: 'filled' },
        tabBar: { activeColor: 'primary' },
    },
    boot: { background: ['#15171B'] },
    navigation: { home: 'store', languageSwitcher: true },
});

Your editor checks it as you type: defineBranding is typed, and every value is validated when the app starts.

Options

Colors

FieldValues
colors.presetblue, red, green, indigo, orange, truevegan: the starting palette
colors.light, colors.darkOverrides for the semantic colors: background, surface, color, textPrimary, textSecondary, textPlaceholder, primary, primaryBorder, primaryText, secondary, secondaryBorder, borderColor, borderColorWithShadow, shadowColor, borderActive, and success, error, warning, info with their …Border and …Text variants
colors.extra.all, .light, .darkMore theme keys: gradientStart and gradientEnd for gradient buttons, surface2, or your own (e.g. custom, customBorder, customText for a custom tab bar)

Colors are hex (#rgb, #rrggbb, #rrggbbaa), rgb()/rgba(), white, black or transparent. Text and background pairs are checked against WCAG AA (4.5:1 for body text, 3:1 for secondary text); a pair that fails is reported while you develop.

Appearance

FieldValues
appearance.defaultSchemesystem (default, follows the device), light or dark
appearance.allowUserToggletrue (default) lets customers choose system, light or dark in their account

Typography

FieldValues
typography.body, typography.heading{ family, faces }: the family name and, per weight ('100'–'900'), the PostScript name of a font file in brand/fonts. heading defaults to body
typography.scale0.85–1.3 (default 1): scales every text style

Components and shape

FieldValues
components.productCard.variantbordered (default), outlined or visio (image-led, name and price over the photo)
components.storeCategories.displaygrid (default) or pills on the store page
components.storeHeadershowGradient, showLocationPicker, showTitle, showDescription, showLogo, logoHeight, logoWidth, direction, alignItems, justifyContent, spacing, paddingTop/Bottom/Left/Right
components.button.fillsolid (default) or gradient: main buttons filled from gradientStart to gradientEnd
components.button.radius0–32 (default 12)
components.chip.selectedtinted (default) or filled
components.tabBar.activeColorThe theme key of the active tab, e.g. primary
shape.radius.tile, .card, .sheetCorner radii of tiles (12), cards (16) and sheets (24)

Images and boot screen

FieldValues
assets.loginBackground, assets.bootBackground{ bundled: 'storefront_photo_1' }, { url: 'https://…' } or null
boot.background1–4 colors (or $tokens) behind the boot screen; more than one makes a gradient
FieldValues
navigation.homestore (default) or foodTrucks
navigation.store.tabs, .defaultTab, .tabBar.backgroundA single store's tabs, its first tab, and blur or a theme key for the tab bar
navigation.network.tabs, .mainStoreTag, .foodTrucksA Network's tabs, the tag of its main store, and the Trucks tab
navigation.foodTrucksViewmap (default) or list
navigation.tabs.<Tab>{ icon, label } for one tab
navigation.languageSwitchertrue (default) shows a language button in screen headers when more than one language is offered
screens.<screen id>.variantA built-in alternative of a screen, e.g. { 'network.home': { variant: 'shop' } }

What each home screen and tab does: Home Screens & Tabs.

Fonts

Put the font files in brand/fonts, each named after its PostScript name: GolosText-Regular.ttf, GolosText-Bold.ttf (.ttf, .otf, .woff, .woff2).

Declare them under typography in the brand file, as in the example above.

Link them into the native projects with npx react-native-asset, then rebuild. The web build loads them on its own.

Every text style uses the body font; titles and headings use the heading font. A declared face missing from brand/fonts falls back to the system font.

App icon and launch screen

Put your artwork in brand/:

FileWhat it is
brand/app-icon.png1024×1024, no transparency (iOS rejects icons with an alpha channel)
brand/splash-screen.pngThe logo on the launch screen; a white or single-color logo on a transparent background works best

Then generate every size for iOS and Android:

yarn generate:app-icon
yarn generate:launch-screen

The launch screen's background is the brand file's boot.background, or pass --background=#hex. The in-app boot screen that follows shows the same brand/splash-screen.png, so the two match. Without a brand/ artwork file, the templates in assets/ are used.

Copy

brand/translations/<locale>.json is merged over the app's own strings. Change any of them, or add keys for your own tab labels and screens:

{ "Shop": { "searchPlaceholder": "Search rice, flour, oil…" } }

A file for a language the app doesn't ship adds that language; offer it with AVAILABLE_LOCALES.

How the brand is resolved

Branding is built from these sources, each overriding the one before:

  1. The app's defaults.
  2. Older .env branding keys, so existing builds keep their look.
  3. brand/storefront.brand.ts, or the empty template at the repository root when a build has none.
  4. A local preview (debug builds only, below).

Each value is validated on its own: an invalid one is dropped and the next source's value is used, so one bad color never discards the rest. A file with an unsupported schemaVersion is ignored.

Previewing colors

In a debug build, store a branding config under storefront:branding-preview and restart to try colors without rebuilding. On the web:

localStorage.setItem('storefront:branding-preview', JSON.stringify({ schemaVersion: 1, colors: { light: { primary: '#be185d' } } }));
location.reload();

Remove the key to go back to the build's branding. Release builds ignore previews.

In your own screens

Screens you add read the brand through useBranding() and style themselves with theme tokens ($primary, $textSecondary) and the app's components (src/ui), so they follow the brand and both appearances without extra work. See Extending.

Branding | Fleetbase