Skip to content

Branding

The kit ships a public site: a landing page, a pricing section and two legal pages, all of them wearing a brand that is not yours. Making them yours is two files, and this page is the map of which half goes where.

config/brand.php        names, addresses, URLs, marks
lang/{locale}/app.php   every sentence a visitor reads

The split is not arbitrary. A product name is one string whatever language the page is in; a tagline is one string per language, and a config file has no locale. So anything with a name, a URL or an address in it lives in the config, and anything with a verb in it lives in the language files.

The configuration

php
// config/brand.php
return [
    'name' => env('BRAND_NAME', env('APP_NAME', 'Laravel')),
    'company' => env('BRAND_COMPANY', env('APP_NAME', 'Laravel')),
    'address' => env('BRAND_ADDRESS', '1 Example Street, 00000 Somewhere'),
    'email' => env('BRAND_EMAIL', 'hello@example.com'),
    'logo' => env('BRAND_LOGO'),
    'favicon' => env('BRAND_FAVICON', '/favicon.svg'),
    'og_image' => env('BRAND_OG_IMAGE', '/og-image.png'),
    'color' => env('BRAND_COLOR', '#171717'),
    'links' => [
        'docs' => env('BRAND_DOCS_URL'),
        'twitter' => env('BRAND_TWITTER_URL'),
        'github' => env('BRAND_GITHUB_URL'),
    ],
    'legal' => ['updated_at' => env('BRAND_LEGAL_UPDATED_AT', '2026-01-01')],
];

Every value is an environment variable with a default, so a deployment can change the address without a code change and a fresh clone still boots.

name and company are different words on purpose. The product is what the navigation says; the company is the entity that signs a contract, and only one of those belongs in a terms of service. They default to the same value because on day one they usually are.

address is not optional. A privacy policy has to say who is responsible for the data and where to reach them, and LARASPRING_MAIL_ADDRESS needs the same line for the footer of anything a recipient could call marketing. .env.example points the mail keys at the brand values, so it is stated once:

dotenv
LARASPRING_MAIL_PRODUCT_NAME="${BRAND_NAME}"
LARASPRING_MAIL_PRIMARY_COLOR="${BRAND_COLOR}"
LARASPRING_MAIL_ADDRESS="${BRAND_COMPANY}, ${BRAND_ADDRESS}"

A link that is not set is not drawn. docs is the entry in the public navigation and the footer; the rest are social icons. Adding linkedin is a key here plus one entry in the icon map at the top of components/marketing/site-footer.tsx, or SiteFooter.vue in the Vue edition.

Marks

logo is a URL to your artwork, and leaving it null draws the mark in components/app-logo-icon.tsx (AppLogoIcon.vue) instead. Both the built-in mark and public/favicon.svg are deliberately plain: a placeholder should look unfinished, so that shipping with it still in place is a thing you notice.

og_image is the picture in a link preview. Out of the box it is public/og-image.png, a 1200×630 placeholder carrying the kit's own wordmark and drawn from public/og-image.svg next to it, so a shared link is not blank on the first day. Replace both files, or point the key at your own image. Set BRAND_OG_IMAGE to nothing and the tag is omitted entirely rather than pointed at a file that does not exist, which is the right answer while you have no artwork: a broken preview card is worse than no card.

Colours

brand.color is the browser theme colour and the value to keep LARASPRING_MAIL_PRIMARY_COLOR in step with. It is not the interface palette.

The palette is --primary and its neighbours in resources/css/app.css, in the :root block and again in .dark. Tailwind resolves those at build time, so no value read at runtime could ever reach them; changing the accent of the application means editing that file and running npm run build. Change both blocks, or the product has a brand in one theme and not the other.

Reaching the brand from your own code

config('brand.name') anywhere in PHP. In a page it is a shared prop, and the two editions read it the same way apart from the syntax around it:

tsx
const { brand } = usePage<SharedData>().props;

The prop is built by HandleInertiaRequests::brand(), which lists the keys it publishes rather than sharing the file wholesale. Add a key to that method when a page needs it; the list is what stops a value added to the config for the server from being published to every browser by accident.

What is still yours to do

  • Replace public/favicon.svg and the logo component, or set brand.logo.
  • Replace public/og-image.png and its .svg source, or set BRAND_OG_IMAGE.
  • Rewrite the copy: see Marketing pages.
  • Decide whether you want Analytics. Nothing is loaded until you do, so the choice is yours to make rather than yours to undo.
  • Have a lawyer read the legal pages before you publish them. They ship as a template, and they say so on the page until you remove the banner.

Laraspring is a commercial starter kit. Buying it gets you the source.