Skip to main content

Overview

Better Auth Studio supports extensive customization through the metadata configuration. Personalize the studio to match your brand identity when self-hosting.
Self-Hosting Only: Custom branding is available when self-hosting the studio. The CLI version uses default branding.

StudioMetadata Type

The complete metadata configuration interface:
type StudioMetadata = {
  title?: string;
  logo?: string;
  favicon?: string;
  company?: {
    name?: string;
    website?: string;
    supportEmail?: string;
  };
  theme?: "dark" | "light" | "auto";
  colors?: {
    primary?: string;
    secondary?: string;
    accent?: string;
  };
  features?: {
    users?: boolean;
    sessions?: boolean;
    organizations?: boolean;
    analytics?: boolean;
    tools?: boolean;
    security?: boolean;
  };
  links?: Array<{ label: string; url: string }>;
  custom?: Record<string, any>;
};

Basic Configuration

Title Customization

Set a custom title for your studio:
// studio.config.ts
import type { StudioConfig } from "better-auth-studio";
import { auth } from "./lib/auth";

const config: StudioConfig = {
  auth,
  basePath: "/api/studio",
  metadata: {
    title: "My Company Admin Dashboard",
  },
};

export default config;
The title appears in the browser tab and the studio header.

Theme Selection

Choose between dark, light, or auto themes:
metadata: {
  title: "Admin Dashboard",
  theme: "dark", // Force dark theme
}
Theme Options:
  • "dark" - Always use dark theme
  • "light" - Always use light theme
  • "auto" - Follow system/browser preference (default)

Visual Branding

Logo Customization

1

Prepare logo asset

  • Format: PNG, SVG, or JPG
  • Recommended size: 200x60px
  • Background: Transparent (for PNG/SVG)
2

Host logo file

Place in your public directory:
/public/branding/logo.png
3

Configure logo path

metadata: {
  logo: "/branding/logo.png",
}
Logo Configuration:
metadata: {
  title: "Acme Corp Admin",
  logo: "/branding/acme-logo.svg",
  // Logo appears in header and login screen
}
Use SVG format for logos to ensure crisp rendering at any size.

Favicon

Set a custom favicon for browser tabs:
metadata: {
  title: "Admin Dashboard",
  favicon: "/favicon.ico",
}
Favicon Formats:
  • .ico - Best browser compatibility
  • .png - Modern browsers (16x16, 32x32, 48x48)
  • .svg - Scalable, modern browsers

Color Customization

Primary Colors

Customize the main color scheme:
metadata: {
  title: "Admin Dashboard",
  theme: "dark",
  colors: {
    primary: "#3b82f6",   // Blue
    secondary: "#8b5cf6", // Purple
    accent: "#10b981",    // Green
  },
}

Color Definitions

Usage:
  • Main buttons and CTAs
  • Active navigation items
  • Links and interactive elements
  • Focus states
colors: {
  primary: "#3b82f6", // Tailwind blue-500
}
Usage:
  • Secondary buttons
  • Badges and tags
  • Sidebar highlights
  • Hover states
colors: {
  secondary: "#8b5cf6", // Tailwind purple-500
}
Usage:
  • Success messages
  • Highlights and emphasis
  • Status indicators
  • Special UI elements
colors: {
  accent: "#10b981", // Tailwind green-500
}

Color Format

Supported color formats:
colors: {
  primary: "#3b82f6",
  secondary: "#8b5cf6",
  accent: "#10b981",
}

Company Information

Company Metadata

Add your company details:
metadata: {
  title: "Admin Dashboard",
  company: {
    name: "Acme Corporation",
    website: "https://acme.com",
    supportEmail: "[email protected]",
  },
}
Display Locations:
  • Footer
  • About/help sections
  • Email templates
  • Support links

Feature Toggles

Disable Features

Hide specific studio sections:
metadata: {
  title: "Admin Dashboard",
  features: {
    users: true,          // Show users section
    sessions: true,       // Show sessions
    organizations: false, // Hide organizations
    analytics: true,      // Show analytics
    tools: false,        // Hide tools section
    security: true,      // Show security settings
  },
}
Hiding features only affects the UI. API endpoints remain accessible unless you implement additional authorization.

Use Cases

features: {
  users: true,
  sessions: true,
  organizations: false,
  analytics: false,
  tools: false,
  security: true,
}
Only show user and session management.
features: {
  users: true,
  sessions: true,
  organizations: true,
  analytics: true,
  tools: false,        // Hide dev tools in production
  security: true,
}
Hide development tools in production.
Add custom navigation links:
metadata: {
  title: "Admin Dashboard",
  links: [
    { label: "Documentation", url: "https://docs.example.com" },
    { label: "Support", url: "https://support.example.com" },
    { label: "Main App", url: "https://app.example.com" },
    { label: "API Docs", url: "/api/docs" },
  ],
}
Link Properties:
  • label - Display text
  • url - Destination URL (absolute or relative)
Links appear in the studio navigation menu for quick access to related resources.

Custom Metadata

Arbitrary Data

Store additional custom data:
metadata: {
  title: "Admin Dashboard",
  custom: {
    environment: "production",
    version: "2.0.0",
    buildDate: "2024-03-03",
    features: ["sso", "2fa", "audit-logs"],
    supportTier: "enterprise",
  },
}
Use Cases:
  • Environment indicators
  • Version information
  • Feature flags
  • Analytics tracking
  • Custom integrations

Complete Example

Full Branding Configuration

// studio.config.ts
import type { StudioConfig } from "better-auth-studio";
import { auth } from "./lib/auth";

const config: StudioConfig = {
  auth,
  basePath: "/api/studio",
  
  metadata: {
    // Basic branding
    title: "Acme Corp Admin Dashboard",
    logo: "/branding/acme-logo.svg",
    favicon: "/branding/favicon.ico",
    
    // Company info
    company: {
      name: "Acme Corporation",
      website: "https://acme.com",
      supportEmail: "[email protected]",
    },
    
    // Theme and colors
    theme: "dark",
    colors: {
      primary: "#3b82f6",
      secondary: "#8b5cf6",
      accent: "#10b981",
    },
    
    // Feature toggles
    features: {
      users: true,
      sessions: true,
      organizations: true,
      analytics: true,
      tools: false, // Hide in production
      security: true,
    },
    
    // Custom links
    links: [
      { label: "Documentation", url: "https://docs.acme.com" },
      { label: "Support Portal", url: "https://support.acme.com" },
      { label: "Main Application", url: "https://app.acme.com" },
    ],
    
    // Custom metadata
    custom: {
      environment: process.env.NODE_ENV,
      version: "2.1.0",
      region: "us-east-1",
    },
  },
  
  access: {
    roles: ["admin"],
    allowEmails: ["[email protected]"],
  },
};

export default config;

Environment-Based Branding

Different Configs Per Environment

// studio.config.ts
import type { StudioConfig } from "better-auth-studio";
import { auth } from "./lib/auth";

const isDev = process.env.NODE_ENV === "development";
const isStaging = process.env.NODE_ENV === "staging";

const config: StudioConfig = {
  auth,
  basePath: "/api/studio",
  
  metadata: {
    title: isDev 
      ? "[DEV] Admin Dashboard" 
      : isStaging
      ? "[STAGING] Admin Dashboard"
      : "Admin Dashboard",
    
    theme: "dark",
    
    colors: {
      primary: isDev ? "#f59e0b" : "#3b82f6", // Orange in dev
      secondary: "#8b5cf6",
      accent: "#10b981",
    },
    
    features: {
      users: true,
      sessions: true,
      organizations: true,
      analytics: true,
      tools: isDev || isStaging, // Only in dev/staging
      security: true,
    },
    
    custom: {
      environment: process.env.NODE_ENV,
      apiUrl: process.env.API_URL,
    },
  },
};

export default config;

Browser Integration

How Metadata is Injected

The studio injects metadata into the HTML:
<!DOCTYPE html>
<html>
<head>
  <title>Admin Dashboard</title>
  <link rel="icon" href="/branding/favicon.ico" />
  <script>
    window.__STUDIO_CONFIG__ = {
      basePath: "/api/studio",
      metadata: {
        title: "Admin Dashboard",
        theme: "dark",
        colors: { /* ... */ },
        // ...
      }
    };
  </script>
</head>
<body>
  <!-- Studio app -->
</body>
</html>

Accessing Config in Frontend

Custom frontend code can access the config:
// Access studio config from browser
const studioConfig = (window as any).__STUDIO_CONFIG__;

console.log(studioConfig.metadata.title);
console.log(studioConfig.metadata.custom);

Best Practices

Match your studio branding to your main application:
  • Use same logo
  • Match color scheme
  • Consistent typography
  • Unified theme
Ensure your color choices meet accessibility standards:
  • Sufficient contrast ratios (WCAG AA/AAA)
  • Test with colorblind simulators
  • Support both dark and light themes
Optimize branding assets:
  • Compress images
  • Use appropriate formats (SVG for logos)
  • Lazy load large assets
  • Cache static resources
Make environments visually distinct:
  • Different colors per environment
  • Environment name in title
  • Visual badges/indicators

Next Steps

Self-Hosting

Deploy your customized studio

Access Control

Secure your studio instance

CLI Usage

Master the CLI options

Troubleshooting

Common issues and solutions

Build docs developers (and LLMs) love