Home > other >  "className did not match" in local dev only
"className did not match" in local dev only

Time:02-17

I am developing an application using NextJS, React, and Styled Components. My application looks/works fine in production, but when I am running it locally for development the components used in _app.tsx are unstyled and I see the className did not match error in the browser console.

  • NextJS 12.0.7
  • React 17.0.2
  • Styled Components 5.3.3
  • babel-plugin-styled-components 2.0.2

Here's my .babelrc file:

{
  "presets": ["next/babel"],
  "plugins": [["styled-components", { "ssr": true }], "superjson-next"]
}

Why is this only happening when I run the app locally and how do I fix It?

Production Screenshot

Local Development: Local Development Screenshot

Here's the code for the NavBar.tsx component that is having rendering issues:

import { CreateDeckButton } from 'components/CreateDeckButton'
import { Button, colors } from 'components/ui'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { FC } from 'react'
import styled from 'styled-components'
import { useMe } from 'utils'

export const NavBar: FC = () => {
  const { me, isLoading, isError } = useMe()
  const { asPath } = useRouter()

  function getUrl(url: string) {
    return asPath === '/' ? url : `${url}?returnTo=${asPath}`
  }

  let actions = (
    <Button href={getUrl('/api/auth/login')} as="a" variant="neutral">
      Login
    </Button>
  )

  if (isLoading) {
    actions = <span>Loading...</span>
  }

  if (isError) {
    actions = (
      <Button href={getUrl('/api/auth/login')} as="a" variant="neutral">
        Login
      </Button>
    )
  }

  if (me) {
    actions = (
      <>
        <p>
          Logged in as <strong>{`@${me.handle}`}</strong>
        </p>
        <Button href={getUrl('/api/auth/logout')} as="a" variant="primary">
          Logout
        </Button>
      </>
    )
  }

  return (
    <Header>
      <Left>
        <Link href="/">
          <Logo>Sol Ring</Logo>
        </Link>
        <Link href="/decks">
          <Button as="a" variant="neutral">
            Decks
          </Button>
        </Link>
        <Link href="/gatherer">
          <Button as="a" variant="neutral">
            Gatherer
          </Button>
        </Link>
        <CreateDeckButton />
      </Left>
      <Actions>{actions}</Actions>
    </Header>
  )
}

const Header = styled.header`
  flex: 0 0 80px;
  display: flex;
  align-items: center;
  background-color: ${colors.n1};
  color: ${colors.n7};
  padding: 0 30px;
  justify-content: space-between;
`

const Left = styled.div`
  display: flex;
  align-items: center;

  & > button,
  & > a {
    margin-left: 16px;
  }
`

const Logo = styled.h1`
  font-size: 16px;
  font-weight: bold;
  margin: 0;
  line-height: 1em;
  text-transform: uppercase;
  margin-right: 16px;
`

const Actions = styled.div`
  display: flex;
  align-items: center;

  & > button,
  & > a {
    margin-left: 16px;
  }
`

CodePudding user response:

I was able to fix my issue by changing my .babelrc file to the following:

{
  "presets": ["next/babel"],
  "plugins": ["styled-components", "superjson-next"]
}

CodePudding user response:

you can ditch babelrc altogether with Next 12, then you'll be able to use the full power of the SWC Compiler. Try this config out in your next.config.js file and delete your .babelrc file

const { withSuperjson } = require("next-superjson");

require("eslint-config-next/parser");

const {
  env: { ANALYZE }
} = process;

// @ts-check
/**
 * @type {import('next').NextConfig}
 **/

module.exports = withSuperjson()({
  webpack(config, options) {
    config.experiments = config.experiments || {};
    // allows for async imports within fuctions
    config.experiments.topLevelAwait = true;
    return config;
  },
  swcMinify: true,
  webpack5: true,
  sourceMaps: {
    productionBrowserSourceMaps: true
  },
  experimental: {
    // ssr and displayName are configured by default
    styledComponents: true,
  },
  images: {
    formats: ["image/avif", "image/webp"],
    domains: [
      "avatars.githubusercontent.com",
      "secure.gravatar.com",
      "en.gravatar.com",
      "unsplash.com",
      "images.unsplash.com",
      "tailwindui.com",
      "gravatar.com",
      "images.unsplash.com",
      "lh3.googleusercontent.com"
    ]
  },
  reactStrictMode: true
});

console.log("[next.config.js]: ", JSON.stringify(module.exports, null, 2));
  • Related