Metronic React
Getting Started

Dark Mode

How to use dark mode features in Metronic React.

Metronic React provides built-in dark mode support using next-themes. For details on the theme provider implementation, see the Providers guide.

Basic Usage

import { useTheme } from 'next-themes';
 
function DarkModeToggle() {
  const { theme, setTheme } = useTheme();
 
  return (
    <button
      onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
    >
      {theme === 'dark' ? 'Switch to Light' : 'Switch to Dark'}
    </button>
  );
}

Theme Options

function ThemeSelector() {
  const { theme, setTheme } = useTheme();
 
  return (
    <select value={theme} onChange={(e) => setTheme(e.target.value)}>
      <option value="light">Light</option>
      <option value="dark">Dark</option>
      <option value="system">System</option>
    </select>
  );
}

Using resolvedTheme

When working with the system theme, use resolvedTheme for accurate styling:

function ThemeAwareComponent() {
  const { resolvedTheme } = useTheme();
 
  return (
    <div className="p-4 rounded-lg shadow-md">
      {resolvedTheme === 'dark' ? (
        <span className="text-blue-300">Dark mode content</span>
      ) : (
        <span className="text-blue-700">Light mode content</span>
      )}
    </div>
  );
}

TailwindCSS Dark Mode

The simplest way to create dark mode styles is with Tailwind's dark variant:

function DarkModeCard() {
  return (
    <div className="bg-white dark:bg-gray-800 text-gray-900 dark:text-white p-4 rounded-md shadow-md">
      <h2 className="text-xl font-bold text-primary-600 dark:text-primary-400">
        Dark Mode Compatible
      </h2>
      <p className="mt-2 text-gray-600 dark:text-gray-300">
        This card adapts to your theme preference automatically.
      </p>
      <button className="mt-4 bg-primary-500 hover:bg-primary-600 dark:bg-primary-600 dark:hover:bg-primary-700 text-white px-4 py-2 rounded">
        Action Button
      </button>
    </div>
  );
}

Handling Images in Dark Mode

Conditionally load appropriate images for the current theme:

function ThemeAwareImage() {
  const { resolvedTheme } = useTheme();
 
  return (
    <img
      src={resolvedTheme === 'dark'
        ? '/images/logo-dark.svg'
        : '/images/logo-light.svg'
      }
      alt="Logo"
      className="h-8 w-auto"
    />
  );
}

Preventing Hydration Mismatch

Since theme information isn't available during server rendering, prevent hydration mismatches:

import { useState, useEffect } from 'react';
import { useTheme } from 'next-themes';
 
function SafeThemeToggle() {
  const [mounted, setMounted] = useState(false);
  const { theme, setTheme } = useTheme();
 
  // Wait for component to mount to access theme
  useEffect(() => {
    setMounted(true);
  }, []);
 
  if (!mounted) {
    // Return placeholder with same dimensions
    return <div className="w-8 h-8" />;
  }
 
  return (
    <button
      className="w-8 h-8 rounded-full flex items-center justify-center"
      onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}
    >
      {theme === 'dark' ? '☀️' : '🌙'}
    </button>
  );
}

Dark Mode with CSS Variables

Access theme variables within your components:

function ThemedComponent() {
  return (
    <div
      style={{
        backgroundColor: 'var(--background)',
        color: 'var(--foreground)',
        borderColor: 'var(--border)'
      }}
      className="p-4 border rounded"
    >
      <h3 className="font-medium">Using CSS Variables</h3>
      <p>This component uses theme CSS variables.</p>
    </div>
  );
}