Quickback Docs

Customization

Customize branding, labels, and messaging in the Account UI

Customization

Customize the Account UI to match your brand and messaging.

Standalone (template): Configure via environment variables, edit src/config/app.ts directly, or use setAppConfig() for runtime overrides.

Library (npm): Configure entirely via setAppConfig(). Import it from quickback-better-auth-account-ui instead of @/config/app.

Library imports

All setAppConfig examples below use the standalone import path (@/config/app). If you're using library mode, replace with:

import { setAppConfig } from 'quickback-better-auth-account-ui';

Branding

App Identity

Set your application's name and description:

VITE_APP_NAME=Acme SaaS
VITE_APP_TAGLINE=Build faster, ship sooner
VITE_APP_DESCRIPTION=The complete platform for modern web applications

These values appear in:

  • Page titles (<title>Acme SaaS | Login</title>)
  • Meta descriptions
  • UI headers and footers
  • Email templates

Visual Identity

# Primary theme color (used for buttons, links, accents)
VITE_THEME_COLOR=#3b82f6

# Company name (shown in footer, legal pages)
VITE_COMPANY_NAME=Acme Corporation

# Company address (shown in footer, receipts)
VITE_COMPANY_ADDRESS=123 Main St, Suite 100, San Francisco, CA 94105

Logo and Favicon

Place your branding assets in the public/ directory:

public/
├── logo.png          # Main logo (shown in header)
├── favicon.ico       # Browser favicon
└── og-image.png      # Social media preview image

Then update the paths in src/config/app.ts:

src/config/app.ts
branding: {
  primaryColor: "#1e293b",
  logoUrl: "/logo.png",
  faviconUrl: "/favicon.ico"
},

Or set them at runtime in src/main.tsx:

import { setAppConfig } from '@/config/app';

setAppConfig({
  branding: {
    logoUrl: '/logo.png',
    faviconUrl: '/favicon.ico',
  },
});

Custom Labels

Override default UI labels using runtime configuration:

import { setAppConfig } from '@/config/app';

setAppConfig({
  labels: {
    terms: 'Terms and Conditions',
    privacy: 'Privacy Notice',
    support: 'Help Center',
    company: 'My Company',
    organizations: 'Workspaces',  // Rename "Organizations" to "Workspaces"
  },
});

Available Labels

LabelDefaultUsage
terms"Terms of Service"Footer link text
privacy"Privacy Policy"Footer link text
support"Contact Support"Footer link text
company(from VITE_COMPANY_NAME)Footer company name
organizations"Organizations"Navigation and page titles

Custom Messages

Customize user-facing messages:

import { setAppConfig } from '@/config/app';

setAppConfig({
  messages: {
    noOrganizations: "You haven't joined any workspaces yet.",
    contactAdminForInvite: "Contact your team lead to get access.",
    noPendingInvitations: "No pending invites at this time",
    createOrganization: "Create Workspace",
    // ... more messages
  },
});

Available Messages

MessageDefaultUsage
noOrganizations"You're not a member of any organizations yet."Empty organizations list
contactAdminForInvite"Contact an admin to be invited to an organization."Organizations page help text
noPendingInvitations"You have no pending invitations"Empty invitations list
createOrganization"Create Organization"Button text
accountInformation"Account Information"Profile section header
timezone"Timezone"Label for timezone field
serverLocation"Server Location"Label for server location
memberSince"Member since"Account age label
pendingInvitations"Pending Invitations"Section header
invitedAs"Invited as"Invitation role label
accept"Accept"Accept invitation button
decline"Decline"Decline invitation button
userFallback"User"Fallback for missing name
noEmailProvided"No email provided"Fallback for missing email
more"More"Pagination/load more text
total"total"Total count label
active"Active"Active status label
new"New"New item label

Route Customization

Customize route paths using runtime configuration:

import { setAppConfig } from '@/config/app';

setAppConfig({
  routes: {
    public: {
      home: '/',
      login: '/sign-in',        // Change from /login
      signup: '/sign-up',       // Change from /signup
      forgotPassword: '/reset-password',
      welcome: '/getting-started',
    },
    authenticated: {
      dashboard: '/dashboard',
      profile: '/my-account',
      settings: '/preferences',
    },
    organizations: {
      list: '/workspaces',                    // Rename route
      create: '/workspaces/new',
      detail: (slug) => `/workspaces/${slug}`,
    },
  },
});

Route Configuration Limitations

Route changes via runtime config only affect client-side routing and internal links. External links to your Account UI should use the actual deployed routes (default paths).

Password Requirements

Customize password validation rules:

import { setAppConfig } from '@/config/app';

setAppConfig({
  auth: {
    passwordRequirements: {
      minLength: 12,              // Minimum password length
      maxLength: 128,             // Maximum password length
      requireUppercase: true,     // Must have uppercase letter
      requireLowercase: true,     // Must have lowercase letter
      requireNumbers: true,       // Must have number
      requireSymbols: true,       // Must have special character
    },
  },
});

Password requirements are displayed to users during signup and password changes.

Session Duration

Control how long users stay logged in:

import { setAppConfig } from '@/config/app';

setAppConfig({
  auth: {
    sessionDuration: 7 * 24 * 60 * 60,  // 7 days in seconds
  },
});

Email Customization

Configure email sender information:

VITE_EMAIL_FROM=noreply@acme.com
VITE_EMAIL_REPLY_TO=support@acme.com
VITE_SUPPORT_EMAIL=help@acme.com

The fromName is automatically set to VITE_APP_NAME:

// Emails will show:
// From: "Acme SaaS <noreply@acme.com>"

URL Configuration

Configure URLs for external links:

# Main application (redirected to after login)
VITE_APP_URL=https://app.acme.com

# Organization/tenant URL pattern
VITE_TENANT_URL_PATTERN=/workspace/{slug}

# Support pages
VITE_SUPPORT_URL=https://help.acme.com
VITE_PRIVACY_URL=https://acme.com/legal/privacy
VITE_TERMS_URL=https://acme.com/legal/terms

Tenant URL Patterns

The tenant URL pattern supports flexible organization routing:

# Path-based routing
VITE_TENANT_URL_PATTERN=/organizations/{slug}
# Result: https://app.acme.com/organizations/acme-corp

# Subdomain routing
VITE_TENANT_URL_PATTERN=https://{slug}.acme.com
# Result: https://acme-corp.acme.com

# Custom pattern
VITE_TENANT_URL_PATTERN=/workspace/{slug}/dashboard
# Result: https://app.acme.com/workspace/acme-corp/dashboard

Complete Customization Example

Here's a complete example showing all customization options:

src/main.tsx
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { setAppConfig } from '@/config/app';
import './app/globals.css';
import './custom-styles.css';  // Your custom CSS overrides

// Apply customizations before rendering
setAppConfig({
  name: 'Acme SaaS',
  tagline: 'Build faster, ship sooner',
  description: 'The complete platform for modern web applications',

  branding: {
    primaryColor: '#3b82f6',
    logoUrl: '/acme-logo.png',
    faviconUrl: '/favicon.ico',
  },

  labels: {
    organizations: 'Workspaces',
    terms: 'Terms and Conditions',
    privacy: 'Privacy Notice',
    support: 'Help Center',
  },

  messages: {
    noOrganizations: "You haven't joined any workspaces yet.",
    createOrganization: 'Create Workspace',
    contactAdminForInvite: 'Contact your team lead for access.',
  },

  routes: {
    public: {
      login: '/sign-in',
      signup: '/sign-up',
    },
    organizations: {
      list: '/workspaces',
      create: '/workspaces/new',
      detail: (slug) => `/workspaces/${slug}`,
    },
  },

  auth: {
    passwordRequirements: {
      minLength: 12,
      requireSymbols: true,
    },
    sessionDuration: 7 * 24 * 60 * 60,  // 7 days
  },
});

// Render app
import App from './App';
const root = document.getElementById('root')!;
createRoot(root).render(
  <StrictMode>
    <App />
  </StrictMode>
);

Custom Styles

Override default styles with custom CSS:

custom-styles.css
/* Override primary color */
:root {
  --primary: 59 130 246;  /* Tailwind blue-500 */
  --primary-foreground: 255 255 255;
}

/* Custom logo size */
.logo {
  width: 180px;
  height: auto;
}

/* Custom button styles */
.btn-primary {
  background-color: var(--primary);
  border-radius: 8px;
  font-weight: 600;
}

Import your custom CSS after the Account UI styles:

import './app/globals.css';
import './custom-styles.css';  // Your overrides

Next Steps

On this page