DEV Community 👩‍💻👨‍💻

Cover image for Adding Dark Mode Support to Next.js, and Expo Projects
Evan Bacon
Evan Bacon

Posted on

Adding Dark Mode Support to Next.js, and Expo Projects

👋 Quick tutorial today! Here I'll show you how to setup your universal web & mobile app to use the client device's native color scheme! You can also use this same approach to setup other awesome features like React Native Safe Area Context and Expo Action Sheets! 💙

Tutorial

import React from 'react';
import { AppearanceProvider } from 'react-native-appearance';

export default ({ Component, pageProps }) => {
    return (  
      <AppearanceProvider>
        <Component {...pageProps} />
      </AppearanceProvider>
    )
}
Enter fullscreen mode Exit fullscreen mode
  • [Mobile] Add the Appearance provider to the root of your Expo app in your ./App.js:
import React from 'react';
import { AppearanceProvider } from 'react-native-appearance';

export default function App() {
    return (  
      <AppearanceProvider>
        {/* ... */}
      </AppearanceProvider>
    )
}
Enter fullscreen mode Exit fullscreen mode
  • Now you can use the useColorScheme hook anywhere in your Expo + Next.js app!
import { useColorScheme } from 'react-native-appearance';

function App() {
  const colorScheme = useColorScheme();
  const isDark = colorScheme === 'dark';
  return (<Text style={{ color: isDark ? 'white' : 'black' }}>Hey 👋</Text>)
}
Enter fullscreen mode Exit fullscreen mode

That's it! I use the same approach in my personal portfolio (Demo Image):

Alt Text
Alt Text

React Navigation

If your Expo app is using React Navigation (v4) then you'll want to wrap the navigation like this:

import * as React from 'react';
import { AppearanceProvider } from 'react-native-appearance';
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';

// Can be any navigator
const AppNavigator = createStackNavigator(/* Your routes */)

function ContextNavigator(props) {
  return (
    <AppearanceProvider>
      <AppNavigator {...props} />
    </AppearanceProvider>
  );
}
// Hoist the routes
ContextNavigator.router = AppNavigator.router;

// Export the full navigator
export default createAppContainer(ContextNavigator);
Enter fullscreen mode Exit fullscreen mode

Thanks for reading!

Please let me know if you found any problems! Also if you found this helpful, be sure to share it (possibly by printing the article out and handing it out around town 😄) and of course, smash that random unicorn button! 🦄

Top comments (0)

Visualizing Promises and Async/Await 🤯

async await

☝️ Check out this all-time classic DEV post