question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Next.js 13 appDir support

See original GitHub issue

Opening an issue to track support for Next.js 13’s appDir and server components.

Currently, it’s possible to use next-themes within appDir with the following pattern:

// app/layout.tsx
import * as React from 'react'

import { Providers } from './providers'
import './globals.css'

export default function RootLayout({
  children
}: {
  children: React.ReactNode
}) {
  return (
    <html>
      <head>
      </head>

      <body>
        <Providers>
          {children}
        </Providers>
      </body>
    </html>
  )
}
// app/providers.tsx
'use client'

import { ThemeProvider } from 'next-themes'

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <ThemeProvider>
      {children}
    </ThemeProvider>
  )
}

This works for the most part, including accessing and changing the theme via useTheme.

However, during next dev, we get the following console error hinting at hydration problems:

Warning: Extra attributes from the server: data-theme,style
    at html
    at ReactDevOverlay (webpack-internal:///./node_modules/.pnpm/next@13.0.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/react-dev-overlay/internal/ReactDevOverlay.js:53:9)
    at HotReload (webpack-internal:///./node_modules/.pnpm/next@13.0.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/react-dev-overlay/hot-reloader-client.js:19:11)
    at Router (webpack-internal:///./node_modules/.pnpm/next@13.0.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/app-router.js:74:11)
    at ErrorBoundaryHandler (webpack-internal:///./node_modules/.pnpm/next@13.0.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/error-boundary.js:28:9)
    at ErrorBoundary (webpack-internal:///./node_modules/.pnpm/next@13.0.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/components/error-boundary.js:40:11)
    at AppRouter
    at ServerRoot (webpack-internal:///./node_modules/.pnpm/next@13.0.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/app-index.js:113:11)
    at RSCComponent
    at Root (webpack-internal:///./node_modules/.pnpm/next@13.0.3_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/client/app-index.js:130:11)

And during production (hosted on Vercel), the following hydration errors seem to randomly appear regardless of how much I pair down the example so long as I’m using next-themes in this way:

Error: Minified React error #418; visit https://reactjs.org/docs/error-decoder.html?invariant=418 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.
    at zh (796-3c8db907cc96f9a4.js:9:55756)
    at ...

#145 looks to be a cookies-based approach to solving this issue, but the PR looks stalled and I’m not sure if it’s a working solution or even the best approach. So I wanted to open up an issue here to track suggestions & progress.

Thanks!

Issue Analytics

  • State:open
  • Created 10 months ago
  • Reactions:10
  • Comments:24

github_iconTop GitHub Comments

4reactions
WITScommented, Dec 1, 2022

Okay, just published 0.2.14 which should fix more hydration errors. (Maybe all of them? 🤞)

4reactions
WITScommented, Nov 25, 2022

That pr should be updated to work with Next.js 13.0.3 now. I’m still looking into making further improvements, but you can test the changes through the npm package @wits/next-themes prior to the pr being merged. (Or try running npm i "next-themes@npm:@wits/next-themes" if you want to keep the same imports in your code.)

I’d like to provide some more context on why the current approach uses cookies. Unfortunately, trying to get this working in the app directory without ensuring that the server is rendering the same <html> attributes results in errors. So I reached out to @pacocoursey as well as some members of the Next.js team before starting this work, and they agreed that a cookie-based approach would be the right move.

next/script is a great call! It wasn’t available for the app directory when I first started writing these changes, but it looks like using it with stategy="beforeInteractive" works here. However, doing so inside of a client component (like the existing ThemeProvider still causes it to run too late and the page will flicker un-themed content. Also, by default, that script relies on window.matchMedia to determine the system theme of the user. That isn’t available on the server, so without cookies we still get errors due to a mismatch between client and server rendering during fast refreshes.

Update: Please make sure you use the <ServerThemeProvider> (as outlined here) if you’re trying this out. If you want to have theme switcher UI, you’ll need both the <ServerThemeProvider> in the layout and a <ThemeProvider> in an interactive ("use client") component.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Blog - Next.js 13
The app directory includes support for: Layouts: Easily share UI between routes while preserving state and avoiding expensive re-renders. Server ...
Read more >
Next.js 13: Working with the new app directory - LogRocket Blog
The new app directory works alongside the pages directory to support incremental adoption and provides other new features like server-side ...
Read more >
Next.js 13 App Playground - Vercel
This includes support for: Layouts: Easily share UI while preserving state and avoiding re-renders. Server Components: Making server-first the default for the ...
Read more >
What's New in Next.js 13 - AppSignal Blog
Let's explore the new features and improvements in Next.js 13. ... it coexist with the app directory - or just skip adding app...
Read more >
i18n with Next.js 13 and app directory - DEV Community ‍ ‍
At Next.js Conf, the Vercel team announced Next.js 13 which introduced the new app directory. It... Tagged with nextjs, react, javascript, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found