Customization Guide

Audience: developers and resellers white-labelling or extending WaDesk — themes, branding, the asset build, languages, and the environment settings that change behaviour without touching code.

What You Can Customize

Most white-label changes are no-code: logos, colours, app name, and message footers are admin settings. Deeper changes — restyling, new pages, new translations — touch the front-end build. This page covers both, in roughly increasing order of effort:

  • Themes — the four built-in looks and how the theme switch works.
  • Branding — logos, favicon, app name, and outbound footers.
  • Front-end build — Vite + Tailwind v4, when and how to rebuild.
  • Languages — the translation files and adding a new one.
  • Environment settings — behaviour you change in the .env file.

Themes

The dashboard ships four themes: paper (default), bright, dark, and doodle. The active theme is applied by setting a data-theme attribute on the page; the CSS then styles each theme off it:

html[data-theme="dark"]   .ts-control { ... }
html[data-theme="bright"] .ts-dropdown { ... }
/* paper is the default — no attribute set */

The user's choice is remembered in their browser (a wa-theme cookie) and applied on the very first paint so the page never flashes the wrong theme on reload. The server reads the same cookie so server-rendered parts (notably the logo) match the active theme straight away — the cookie, not a saved profile setting, is the source of truth.

Adding a theme: register the new theme key, add its html[data-theme="..."] rules in the CSS, and add it to the theme switcher. An unknown saved value safely falls back to paper.

Branding & White-Label

Brand assets come from admin settings — no code edits needed:

AssetConfigured at
Per-theme logo (one per theme)Admin → Settings → General
FaviconAdmin → Settings → General
App nameAdmin settings (falls back to the app's configured name)
Billing identity (company, address, tax ID…)Admin → Checkout Settings (printed on invoices)

Logos fall back gracefully: a missing per-theme logo uses the default paper logo, and if no logo is set at all the UI shows a text wordmark instead.

Outbound Message Footers

The footer added to outbound messages is decided per-workspace:

  • If the workspace's plan does not include "remove branding" → the platform's default footer (set by the admin) is used.
  • If the plan does include "remove branding" → the workspace's own footer is used if set, otherwise no footer at all.

The footer is added to plain-text messages and to the footer line on button/interactive messages. Approved WhatsApp templates are excluded — their content cannot be changed after approval. The bridge is given the final footer along with the rest of a number's settings.

No emojis — SVG only. The product's style is inline SVG icons (16×16, currentColor stroke), never emoji. Keep any custom UI, log lines, and message text emoji-free to match.

Front-End Build (Vite + Tailwind v4)

The front-end is compiled with Vite 7 and Tailwind CSS v4. The build has two style entry points — one for the dashboard/admin and one for the public landing pages — plus the main app script, as declared in vite.config.js:

// vite.config.js
laravel({
  input: [
    'resources/css/app.css',       // dashboard / admin / user shell
    'resources/css/frontend.css',  // public landing pages
    'resources/js/app.js',
  ],
  refresh: true,
})

Tailwind v4 is configured in CSS: the colour palette and fonts are defined in an @theme {} block inside the dashboard stylesheet.

Commands (from the project root):

npm install        # install front-end deps (first time)
npm run dev        # dev server with hot reload (development)
npm run build      # compile production assets
Rebuild after any front-end change. Editing the stylesheets or scripts, or adding new Tailwind classes, needs npm run build for production (or a running npm run dev in development). The whole local stack — web server, queue, logs, and the asset build — can be started together with composer dev.

Adding Languages

Translations are flat JSON files in the lang/ directory, keyed by the English source string. WaDesk ships en.json plus 20 translated locales:

lang/
├── en.json   (source)
├── ar.json  bn.json  de.json  es.json  fr.json  he.json  hi.json
├── id.json  it.json  ja.json  ko.json  nl.json  pl.json  pt.json
└── ru.json  th.json  tr.json  ur.json  vi.json  zh-CN.json

Each file maps the original string to its translation:

// lang/fr.json
{
  "Team Inbox": "Boîte de réception d'équipe",
  "Send message": "Envoyer le message"
}

To add a new language:

  1. Copy lang/en.json to lang/<code>.json (e.g. lang/sv.json) and translate the values.
  2. The default and fallback language are set by APP_LOCALE / APP_FALLBACK_LOCALE in the .env file (both en by default); users switch language using the in-app language switcher.
  3. A built-in tool can scan the app for any newly-added text and append it to the translation files, keeping them in sync as you add features.

Right-to-left languages (Arabic, Hebrew, Urdu) are already included, and the UI handles right-to-left layout automatically.

.env Knobs

Behaviour you change without touching code. The most relevant for customization and deployment:

VariableEffect
APP_NAMEDefault app name (admin app_name setting overrides it in the UI).
APP_URLPublic base URL. Must be the real HTTPS domain — used to build media URLs, Twilio StatusCallback, and links Meta must be able to fetch.
APP_LOCALE / APP_FALLBACK_LOCALEDefault + fallback language (both en out of the box).
DB_*MySQL connection (host, port, database, username, password).
QUEUE_CONNECTIONQueue driver — database by default; switch to redis for higher throughput.
CACHE_STORE / SESSION_DRIVERCache + session backends (both database by default).
SERVER_URLThe address of the Node bridge, used by the send path and scheduler.
NODE_WEBHOOK_TOKENShared secret that authenticates the app and the bridge to each other. Must match the value in node/.env.
MAIL_*Outbound email for invoices, notifications, and password resets.

Several of these also have an admin-panel equivalent that takes precedence — for example the default WhatsApp engine, the allowed engines, the Meta API version, and the bridge URL. Prefer the admin UI for those; the .env values act as fallbacks at startup.

After editing .env: clear the config cache (php artisan config:clear, or config:cache in production). Changes are not picked up while a stale cached config exists.

Conventions to Respect

  • Inline SVG icons only — no emoji anywhere in the UI, scripts, or logs.
  • Encrypted credentials — always read and write engine credentials through the provided helpers, never the raw stored value.
  • Engine-aware UI — gate engine-specific features behind the active-engine check so operators never hit a dead end.
  • Rebuild assets after any front-end change; clear the config cache after any .env change.

Related Pages

WaDesk Documentation