Skip to content

[bug]: animated-theme-toggler.tsx #968

Description

@thisha-me

Describe the bug

Problem

AnimatedThemeToggler manages the theme by directly mutating the DOM and localStorage:

document.documentElement.classList.toggle("dark")
localStorage.setItem("theme", newTheme ? "dark" : "light")

This works in plain Vite/React setups, but breaks in Next.js projects using
next-themes (or similar theme context libraries). Because the toggle bypasses
the framework's theme context, useTheme() subscribers never receive the update —
so resolvedTheme stays stale until a full page refresh.

Expected Behavior

Any component consuming useTheme() should reactively update when the toggle fires.

Suggested Fix

Add an optional onToggle callback prop. No breaking changes — existing users
ignore it, framework users wire it up themselves:

interface AnimatedThemeTogglerProps {
  // ...existing props
  onToggle?: (isDark: boolean) => void
}
const applyTheme = () => {
  const newTheme = !isDark
  setIsDark(newTheme)
  document.documentElement.classList.toggle("dark")
  localStorage.setItem("theme", newTheme ? "dark" : "light")
  onToggle?.(newTheme) // notify framework context
}

Usage in Next.js:

const { setTheme } = useTheme()

<AnimatedThemeToggler
  onToggle={(isDark) => setTheme(isDark ? "dark" : "light")}
/>

Environment

  • Next.js (App Router) with next-themes
  • AnimatedThemeToggler from Magic UI

Impact

useTheme().resolvedTheme never updates on toggle — any component depending
on it (colors, WebGL, canvas, etc.) requires a full page refresh to reflect
the new theme.

Affected component/components

animated-theme-toggler

How to reproduce

  1. Create a Next.js app with next-themes configured
  2. Add AnimatedThemeToggler from Magic UI to your navbar
  3. In any other component, subscribe to the theme via useTheme():
   const { resolvedTheme } = useTheme()
   console.log(resolvedTheme)
  1. Click the AnimatedThemeToggler button to switch themes
  2. Observe that resolvedTheme does not update — the console still shows the old value
  3. Refresh the page — now resolvedTheme reflects the correct theme

Expected: resolvedTheme updates instantly on toggle
Actual: resolvedTheme only updates after a full page refresh

Codesandbox/StackBlitz link

No response

Logs

System Info

- OS: macOS
- Browser: Chrome 136
- Next.js: 15.3.2 (App Router)
- next-themes: 0.4.6
- Node.js: v22.x
- Package Manager: npm

Before submitting

  • I've made research efforts and searched the documentation
  • I've searched for existing issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions