> ## Documentation Index
> Fetch the complete documentation index at: https://learn.social.plus/llms.txt
> Use this file to discover all available pages before exploring further.

# Set Preferred Theme

> Switch the UIKit theme (light / dark / system) at runtime, effective immediately — Flutter only

<Info>
  <strong>Flutter UIKit only.</strong> <code>setPreferredTheme</code> is available in the Flutter UIKit from <strong>4.20.20</strong>. Other platforms switch theme through <a href="/uikit/customization/dynamic-ui">Dynamic UI</a> or the device appearance setting.
</Info>

## Overview

By default the UIKit resolves its theme from the `preferred_theme` value in your `config.json` at startup. `setPreferredTheme` lets you **override that value at runtime**, and the whole UIKit re-themes immediately — no restart, no config re-sync.

```dart Flutter theme={null}
import 'package:amity_uikit_beta_service/amity_uikit.dart';

// Force a style, or follow the device setting
AmityUIKit().setPreferredTheme(AmityThemeStyle.dark);
AmityUIKit().setPreferredTheme(AmityThemeStyle.light);
AmityUIKit().setPreferredTheme(AmityThemeStyle.system);
```

## Styles

| Value                    | Effect                              |
| ------------------------ | ----------------------------------- |
| `AmityThemeStyle.light`  | Force the light theme               |
| `AmityThemeStyle.dark`   | Force the dark theme                |
| `AmityThemeStyle.system` | Follow the device dark-mode setting |

## How It Works

<Steps>
  <Step title="Call the API">
    `AmityUIKit().setPreferredTheme(style)` updates the preferred theme held on the `ConfigRepository` singleton.
  </Step>

  <Step title="Whole tree re-themes">
    Every base page, component, and element already watches the config provider, so the change propagates to the entire UIKit tree immediately.
  </Step>

  <Step title="Overrides config.json">
    The runtime value takes precedence over `preferred_theme` from `config.json` for the rest of the app session.
  </Step>
</Steps>

<Note>
  The override lives in memory for the current app session. It is **not** persisted by the UIKit — on the next launch the theme resolves from `config.json` again. Persist the user's choice yourself (e.g. in `SharedPreferences`) and re-apply it on startup if you want it to stick.
</Note>

## Persisting the choice

Save the selection and restore it before your app renders the UIKit:

```dart Flutter theme={null}
import 'package:shared_preferences/shared_preferences.dart';
import 'package:amity_uikit_beta_service/amity_uikit.dart';

const _prefKey = 'preferredTheme';

Future<void> selectTheme(AmityThemeStyle style) async {
  AmityUIKit().setPreferredTheme(style);
  final prefs = await SharedPreferences.getInstance();
  await prefs.setString(_prefKey, style.name);
}

Future<void> restorePreferredTheme() async {
  final prefs = await SharedPreferences.getInstance();
  final saved = prefs.getString(_prefKey);
  if (saved != null) {
    AmityUIKit().setPreferredTheme(
      AmityThemeStyle.values.asNameMap()[saved] ?? AmityThemeStyle.system,
    );
  }
}
```

Call `restorePreferredTheme()` in `main()` before `runApp()`.

## When to Use

✅ In-app **light / dark toggle** driven by a user setting
✅ Following the device appearance without an app restart
✅ Quick theme experiments during development

For remote, non-engineering-driven brand/token changes, use <a href="/uikit/customization/dynamic-ui">Dynamic UI</a> instead.

## Next Steps

<CardGroup cols={2}>
  <Card title="Dynamic UI" href="/uikit/customization/dynamic-ui" icon="wand-magic-sparkles">Remote, config-driven theming</Card>
  <Card title="Component Styling" href="/uikit/customization/component-styling" icon="code">Per-component overrides</Card>
</CardGroup>
