useTheme
With useTheme plugin, switching between auto, dark, and light themes is effortless, just one command does it all.
You just need to install the plugin and use x-use-theme in your HTML like this:
<html x-use-theme>
...
</html>
Requirement:
- Alpinejs (Version 3)
- TailwindCSS (Support Version 3 and 4)
Installation
To use the useTheme plugin, you can install it in two ways:
- - Using npm (as a module):
- - Using a CDN link (script tag):
1. Using npm (as a module):
You can install useTheme using the following command:
npm install alpineuse
Then, you can import it in app.js like this:
// AlpineUse
import useThemePlugin from "alpineuse/src/use-theme";
Alpine.plugin(useThemePlugin);
If you want to use useTheme with Livewire, you should manually bundle Livewire and Alpine, The final result will look like this:
// Livewire and Alpinejs
import {
Livewire,
Alpine,
} from "../../vendor/livewire/livewire/dist/livewire.esm";
// AlpineUse
import useThemePlugin from "alpineuse/src/use-theme";
Alpine.plugin(useThemePlugin);
document.addEventListener("livewire:navigated", useThemePlugin);
Livewire.start();
2. Using a CDN link (script tag):
Just drop the link in the <head> like this:
<html x-use-theme>
<head>
<title>Title</title>
<!-- TailwindCSS CDN -->
<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
<!-- AlpineUse (useTheme) CDN -->
<script src="https://cdn.jsdelivr.net/npm/alpineuse@2.x.x/use-theme/index.min.js"></script>
<!-- Alpine.js CDN -->
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
<style type="text/tailwindcss">
@custom-variant dark (&:where(.dark, .dark *));
</style>
</head>
<body>
...
</body>
</html>
If you want to use useTheme with Livewire as a CDN, you can use it like this:
<html x-use-theme>
<head>
<title>Title</title>
<!-- Assets -->
<script src="https://cdn.jsdelivr.net/npm/alpineuse@2.0.22/dist/use-theme/index.min.js" defer></script>
@vite(['resources/css/app.css', 'resources/js/app.js'])
@livewireStyles
@livewireScript
<!-- Assets -->
<!-- TailwindCSS Config -->
<style type="text/tailwindcss">
@custom-variant dark (&:where(.dark, .dark *));
</style>
<!-- TailwindCSS Config -->
</head>
<body>
...
</body>
</html>
Basic Usage
First, you need to include x-use-theme in your HTML.
<html x-use-theme>
....
</html>
You can set a default value using an attribute x-use-theme="auto".
<!-- You can use auto, dark, or light as a value -->
<html x-use-theme="auto">
...
</html>
You can get a theme using magic Alpine.js, $useTheme
<span x-data x-text="$useTheme.get"></span>
<span x-data x-text="$useTheme.value"></span>
You can set a theme using magic Alpine.js, $useTheme.set
<button x-data x-on:click="$useTheme.set('dark')">
Change to Dark Mode
</button>
<button x-data x-on:click="$useTheme.value = 'light'">
Change to Light Mode (using .value)
</button>
Final result:
You can copy and paste it into your browser and it will work.
<!DOCTYPE html>
<html class="scroll-smooth" x-use-theme>
<head>
<title>Theme Example</title>
<script src="https://unpkg.com/@tailwindcss/browser@4"></script>
<script
src="https://cdn.jsdelivr.net/npm/alpineuse@2.x.x/dist/use-theme/index.min.js"
defer
></script>
<script
src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"
defer
></script>
<style type="text/tailwindcss">
@custom-variant dark (&:where(.dark, .dark *));
</style>
</head>
<body class="bg-white dark:bg-black">
<div class="mb-8 bg-zinc-50 dark:bg-zinc-900">
<h1 class="text-zinc-950 dark:text-zinc-50">Hello World!</h1>
</div>
<div class="flex flex-col gap-y-2 bg-zinc-50 dark:bg-zinc-900" x-data>
<button x-on:click="$useTheme.set('light')">
Change to Light Mode
</button>
<button x-on:click="$useTheme.set('dark')">
Change to Dark Mode
</button>
<button x-on:click="$useTheme.set('auto')">
Change to Auto Mode
</button>
<button x-on:click="$useTheme.value = 'light'">
Change to Light Mode (using .value)
</button>
<button x-on:click="$useTheme.value = 'dark'">
Change to Dark Mode (using .value)
</button>
<button x-on:click="$useTheme.value = 'auto'">
Change to Auto Mode (using .value)
</button>
<p>
Current Theme (using get()):
<span x-text="$useTheme.get()"></span>
</p>
<p>
Current Theme (using .value):
<span x-text="$useTheme.value"></span>
</p>
</div>
</body>
</html>