Toggle 🌒 dark and 🔆 sunny mode using AlpineJS, and TailwindCSS
Tags: alpinejs, tailwindcss, webdev, tutorial
Published: 2021-05-31 03:46:11

Hey 👋


Rinas here.


This is done using some Alpine JS magic 🪄 and I enjoyed implementing it.


---


## 🏎 Let's start

Update your Tailwind config to let it know need dark mode toggle based on class.
```js
// tailwind.config.js
module.exports = {
  darkMode: 'class',
  // ...
}
```



This will let you write `bg-gray-50 dark:bg-black` and show background colours based on the current mode.

```html
<html class="dark">
<body>
  <div class="bg-gray-100 dark:bg-gray-600">
    <!-- ... -->
  </div>
</body>
</html>
```





Now let's try to remove that hardcoded `dark` class in `html` tag and grab the value from `localStorage` using Alpine

```html
<html
  x-data="{ darkMode: localStorage.getItem('dark') === 'true'} "
  x-init="$watch('darkMode', val => localStorage.setItem('dark', val))"
  x-bind:class="{ 'dark': darkMode }"
>
```




### 🤔 Wait, what's going on here?


```
x-data="{ darkMode: localStorage.getItem('dark') === 'true' "
```
`x-data` tells the framework to initialize a new component with the following data object.  In our case, the object is:
```js
{ darkMode: localStorage.getItem('dark') === 'true'}
```
I think of it as a simple variable and setting `darkMode`'s value to either `true` or `false` based on the localStorage item `dark`'s value.


```
x-init="$watch('darkMode', val => localStorage.setItem('dark', val))"
```
`$watch` is a magic property (yup, that's the official terminology 😁) in Alpine used to watch data we have and trigger a function.
`x-init` You might have already guessed it. It runs an expression when a component is initialized.




So good so far? If not, let me know. I'll try to clarify in comments and update this post accordingly

Let's add the button to toggle the theme now.
```html
<button @click="darkMode = !darkMode">
  Toggle Theme
</button>

```

## 🏁 Yup, that's all you need 😎



--- 
Here is the polished version I used in [HIGHSCORE.domains](https://highscore.domains)

![toggle](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n70adi4dfmajrkb62bgk.gif)
 

 
---



This is my first time using AlpineJS and got featured in [Alpine.js Weekly #61](https://buttondown.email/alpinejs/archive/alpinejs-weekly-61/) by @hugo__df 
> [highscore.domains](https://highscore.domains) got a darkmode toggled powered by Alpine and TailwindUI by @onerinas 
![Screenshot 2021-05-31 at 8.07.54 AM](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ajtov32kq6dye84orslu.png)

---
Leaving few links here which might be useful if you want to try this out in your project:

TailwindCSS:

- https://tailwindcss.com/docs/installation
- https://tailwindcss.com/docs/dark-mode#toggling-dark-mode-manually

AlpineJS:

`x-init`
Runs an expression when a component is initialized.
https://github.com/alpinejs/alpine#x-init

`x-data`
Declares a new component scope.
https://github.com/alpinejs/alpine#x-data

`x-bind`
Sets the value of an attribute to the result of a JS expression.
https://github.com/alpinejs/alpine#x-bind

`$watch`
Will fire a provided callback when a component property you "watched" gets changed.
https://github.com/alpinejs/alpine#watch