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




