Skip to main content
Learn how to create beautiful custom themes for UptimeKit status pages. Themes are self-contained plugins that control the appearance and layout of your status pages.

Understanding the Theme System

UptimeKit’s theme system is designed to be simple yet powerful. Themes are pure rendering components that receive data and render the UI. All theming concerns (dark mode, CSS loading, data attributes) are handled automatically.

Key Benefits

  • Zero boilerplate: Theme files are pure rendering components
  • No flash: Theme is set before first paint
  • Simple architecture: Just 2 wrapper files handle all theme logic
  • Auto CSS loading: Custom CSS loaded automatically from manifest
  • Type safe: Proper TypeScript generics throughout

Theme Structure

Creating Your First Theme

Step 1: Create Theme Directory

Create a new directory under app/themes/ with your theme name:

Step 2: Create Manifest

Create manifest.ts with your theme metadata:
app/themes/my-theme/manifest.ts

Step 3: Create Main Page Component

Create page.tsx for the main status page:
app/themes/my-theme/page.tsx

Step 4: Create Other Required Pages

Create incident-detail.tsx:
app/themes/my-theme/incident-detail.tsx
Create maintenance-detail.tsx:
app/themes/my-theme/maintenance-detail.tsx
Create updates.tsx:
app/themes/my-theme/updates.tsx

Step 5: Register Your Theme

Add your theme to app/themes/index.ts:
app/themes/index.ts

Customizing with CSS

The most powerful way to customize your theme is by overriding CSS variables. This allows you to change colors, fonts, shadows, and more without modifying component code.

Creating Custom CSS

Create public/themes/my-theme/style.css:
public/themes/my-theme/style.css

Available CSS Variables

Colors

Status Colors

Typography

Spacing & Effects

See src/index.css for the complete list of available variables.

Data Contracts

All theme pages receive standardized data through props:

ThemePageProps (Main Status Page)

ThemeIncidentDetailProps

ThemeMaintenanceDetailProps

ThemeUpdatesProps

See app/themes/types.ts for complete type definitions.

Component Organization

Extract reusable UI elements into components:
Example component:
app/themes/my-theme/components/status-badge.tsx

Theme Architecture

How It Works

Themes are pure rendering components. All theme setup is handled by two files:
  1. ThemePageWrapper (server component):
    • Renders inline blocking script that sets data-theme and .dark class before first paint
    • Loads theme manifest automatically
    • Renders ThemeProvider for client-side hydration
    • Used by all page dispatchers (app/page.tsx, app/[slug]/page.tsx, etc.)
  2. ThemeProvider (client component):
    • Syncs theme changes when user switches themes
    • Dynamically loads custom CSS from manifest
    • Keeps everything in sync with next-themes
This architecture provides:
  • Zero boilerplate - Theme files are pure rendering components
  • No flash - Inline script sets theme before first paint
  • Simple architecture - Just 2 files handle all theme logic
  • Auto CSS loading - Manifest cssFile loaded automatically
  • Type safe - Proper TypeScript generics throughout

Best Practices

1. Use CSS Variables

Override CSS variables instead of writing custom styles:

2. Support Dark Mode

Always provide dark mode overrides if supportsDarkMode: true:

3. Extract Components

Keep theme files clean by extracting reusable components:

4. Use Tailwind Classes

Leverage Tailwind utility classes that use CSS variables:

5. Follow Type Contracts

Use the provided TypeScript types for props:

Testing Your Theme

Local Development

  1. Set up a local UptimeKit instance following the installation guide
  2. Add your theme files to app/themes/
  3. Register your theme in app/themes/index.ts
  4. Create a test status page and select your theme
  5. Test all pages: main, incident detail, maintenance detail, updates

Test Checklist

  • Main status page renders correctly
  • Incident detail page works
  • Maintenance detail page works
  • Updates page displays properly
  • Dark mode toggles correctly (if supported)
  • Custom CSS loads and applies
  • All monitor statuses display correctly
  • Responsive design works on mobile/tablet
  • Logo and branding display properly
  • Links and navigation work

Example Themes

Study the included example theme for reference:
  • default - Classic design with full uptime history and comprehensive monitoring display

Contributing Your Theme

Once your theme is ready:
  1. Test thoroughly following the checklist above
  2. Create a pull request to the UptimeKit repository
  3. Include screenshots of your theme
  4. Document any special features or requirements
  5. Follow the project’s contribution guidelines

Need Help?

Happy theming!