


Category
Override
Category
Override
Author name
Dávid Kálmán
Author name
Dávid Kálmán
Last Updated
Aug 7, 2024
Last Updated
Aug 7, 2024
Let your visitors choose between light and dark mode using this theme toggle override for Framer.
The toggle works with the Framer built-in light/dark color system, making it easily integrable with new or existing projects.
All you have to do is:
Copy the code below (or remix the project).
Paste the code in a new code override in your project.
Apply it to any frame on your website.
And voilà! You know have a perfectly functioning toggle on your website.
import type { ComponentType } from "react" import { addPropertyControls, ControlType } from "framer" import React, { useEffect, useState } from "react" function getOSTheme() { if (typeof window !== "undefined" && typeof document !== "undefined") { return window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" } return "light" } function setInitialState() { const osTheme = getOSTheme() const currentToggleState = localStorage.getItem("currentToggleState") || (osTheme === "dark" ? "dark" : "light") localStorage.setItem("currentToggleState", currentToggleState) if (typeof document !== "undefined") { const styleTag = document.getElementsByTagName("style")[0] const newCSS = styleTag.innerHTML.replace( /prefers-color-scheme: \w+/, `prefers-color-scheme: ${ (currentToggleState === "dark" && osTheme === "dark") || (currentToggleState === "light" && osTheme === "light") ? "dark" : "light" }` ) styleTag.innerHTML = newCSS } return currentToggleState === "dark" } export function themeSwictherBasedOnSystem(Component): ComponentType { return (props) => { const [isOn, setIsOn] = useState(setInitialState()) const toggle = () => { const newToggleState = !isOn ? "dark" : "light" setIsOn(!isOn) localStorage.setItem("currentToggleState", newToggleState) if (typeof window !== "undefined") { window.dispatchEvent(new CustomEvent("themeChange")) } } useEffect(() => { if (typeof window !== "undefined") { const mediaQuery = window.matchMedia( "(prefers-color-scheme: dark)" ) mediaQuery.addListener((e) => { const newTheme = e.matches ? "dark" : "light" localStorage.setItem("currentOsTheme", newTheme) localStorage.setItem("currentToggleState", newTheme) setIsOn(newTheme === "dark") if (typeof document !== "undefined") { const styleTag = document.getElementsByTagName("style")[0] const newCSS = styleTag.innerHTML.replace( /prefers-color-scheme: \w+/, `prefers-color-scheme: ${ (newTheme === "dark" && newTheme === "dark") || (newTheme === "light" && newTheme === "light") ? "dark" : "light" }` ) styleTag.innerHTML = newCSS } window.dispatchEvent(new CustomEvent("themeChange")) }) } }, []) useEffect(() => { if ( typeof window !== "undefined" && typeof document !== "undefined" ) { const currentToggleState = isOn ? "dark" : "light" const currentOsTheme = localStorage.getItem("currentOsTheme") || getOSTheme() const styleTag = document.getElementsByTagName("style")[0] const newCSS = styleTag.innerHTML.replace( /prefers-color-scheme: \w+/, `prefers-color-scheme: ${ (currentToggleState === "dark" && currentOsTheme === "dark") || (currentToggleState === "light" && currentOsTheme === "light") ? "dark" : "light" }` ) styleTag.innerHTML = newCSS localStorage.setItem("currentToggleState", currentToggleState) } }, [isOn]) const [isClient, setIsClient] = useState(false) useEffect(() => { setIsClient(true) }, []) return <Component {...props} onClick={toggle} /> } }
Check more
free resources
Explore more free components, animations, overrides, and clonables to build better and faster