Set your Web App to Dark/Light Mode based on User System Settings
Tags: react, tutorial, javascript, beginners
Published: 2021-09-05 17:17:18

We all know Dark mode is one of the hottest features from 2019. Everything from smartphones, laptops, and your applications now comes with in-build dark mode.

It comes with a lot of advantages. It's the way forward when spending long hours in front of the laptop under low light.

It also saves significant battery in newer devices using OLED screens by turning off the black pixels.

But, is it the best option to choose all the time over light mode? Let's see.

## The dark mode comes with some disadvantages too. 

Using dark mode when the surrounding is well lit can cause strain to your eyes just like when you use too much light in low light condition. When in the bright surrounding, your eye finds it hard to focus on the content present in the dark background with very little contrast. Therefore, most users switch between dark and light modes in their devices based on their surroundings.

What if, we as developers, can set our web application theme based on the device settings and reduce that extra step to switch in our apps? Will it be possible?
Well, there is a way.

## What is Window.matchMedia() ?

Windows.matchMedia() is a method that returns an object that determines if the document matches the media query string. 

Just like how we use @media in CSS, you can detect the same media queries in javascript.

For example, if we have the following media query in CSS
```
@media screen and (max-width:700px){
}
```

The javascript equivalent is:
```
const mw = window.matchMedia("screen and (max-width:700px)")
```

## Detecting System theme using matchMedia()

Consider a simple React component with a Hello World text written in it.

```
function App() {


  return (
    <div>
      Hello World
    </div>
  );
}

export default App;
```

To add the dark mode to the component, we use the prefers-color-scheme CSS media feature. It detects if the system is in a dark theme or light theme.

The matches property of the prefers-color-scheme is a boolean value that updates based on the query.

So, to check the system preference, we add as isDark variable to detect if the system uses dark mode.
```
function App() {

  const isDark = window.matchMedia("(prefers-color-scheme:dark)").matches

  const lightTheme = {
    backgroundColor : "white",
    color : "black"
  }

  const darkTheme = {
    backgroundColor : "black",
    color : "white"
  }

  return (
    <div style={isDark?darkTheme:lightTheme}>
      Hello World
    </div>
  );
}

export default App;
```

Based on the isDark variable value, either the darkTheme or lightTheme syle applies to the component.

## Option to Switch themes inside the application

We can also add a toggle inside the application if the user wants to switch between the themes.

For that, we create a state variable and initialize it with the system theme settings.

Every time the user clicks the button, the state variable toggles accordingly.

```
import { useState } from 'react';

function App() {

  const isSystemDark = window.matchMedia("(prefers-color-scheme: dark)").matches
  const [isDark,setIsDark] = useState(isSystemDark)

  const lightTheme = {
    backgroundColor : "white",
    color : "black"
  }

  const darkTheme = {
    backgroundColor : "black",
    color : "white"
  }

  return (
    <div style={isDark?darkTheme:lightTheme}>
      Hello World
      <button onClick={()=>setIsDark(toggle =>!toggle)}>Switch Theme</button>
    </div>
  );
}

export default App;
```