Errors I dealt with in Next.js - styled components, pages, types
Dahye Ji
Posted on December 23, 2021
1. Warning : Props 'className' did not match Server: ' ' Client: ' '
I wanted to add styled components so I installed styled-components
yarn add styled-components
and added this code below in package.json
"resolutions": {
"styled-components": "^5"
}
(The code above was recommended if you use a package manager like yarn that supports the "resolutions" package.json field)
and then I imported styled-components and used it.
import styled from "styled-components";
export const StyledLink = styled.a`
border: none;
padding: 0.8rem 1.4rem;
margin: 1rem;
cursor: pointer;
background-color: #2b2b2b;
color: white;
border-radius: 2rem;
font-weight: 600;
&:hover {
background-color: #fc4961;
}
`
like these and but then I got an error saying Warning : Props 'className' did not match Server: ' ' Client: ' ' what it means is it literally doesn't match the className in Server side and in Client side. So, Next.js does SSR first and then CSR partially. The class name doesn't match when it renders and that's why it happened. So to solve this problem, I installed babel-plugin-styled-components
yarn add --dev @types/styled-components babel-plugin-styled-components
and added babelrc
in the root of project directory. Then added this code below
{
"presets": [
"next/babel"
],
"plugins": [
[
"babel-plugin-styled-components",
{
"fileName": true,
"displayName": true,
"pure": true
}
]
]
}
But then I found that I can import { ServerStyleSheet } from 'styled-components';
I think I might have to redo it.
Links I read:
https://stackoverflow.com/questions/51791163/warning-prop-classname-did-not-match-when-using-styled-components-with-seman
https://sumini.dev/guide/004-nextjs-typescript-styled-components/
https://velog.io/@hwang-eunji/Styled-components-nextjs%EC%97%90%EC%84%9C-className-%EC%98%A4%EB%A5%98
Then I got another Error... It was okay when I checked my code through live server but when I deployed them, It kept failing.
2. Build optimization failed: found page without a React Component as default export in pages/styledComponent/styles
But I didn't carefully read those error massages. Only read those lines marked in red and was wondering why it kept failed.
I read the messages line by line then found these Build optimization failed: found page without a React Component as default export in
pages/styledComponent/styles
Link that helped my problem: https://stackoverflow.com/questions/65598753/cant-build-react-next-project-found-page-without-a-react-component-as-default/65598867
You should move your components outside the pages folder. pages/ should only be used for page components as Next.js routing is based on its structure.
My styled-components file was within pages directory... which it shouldn't have been. So I moved it to other directory and it worked fine.
3. Error: Do not use the HTML <a>
tag to navigate to /beers/ale/. Use Link from 'next/link' instead.
I used <a>
tags to link pages and had this problem. So I checked Next.js documentation and added Links like this way
import { NextPage } from "next";
import Link from "next/link";
const BeerPage: NextPage = () => {
return (
<div>
<h1>Beers Page</h1>
<p>
<Link href="beers/ale">
<a>Ale</a>
</Link>
</p>
<p>
<Link href="beers/stouts">
<a>Stouts</a>
</Link>
</p>
<p>
<Link href="beers/red-ale">
<a>Red Ale</a>
</Link>
</p>
</div>
)
}
4. Warning: passHref is missing.
Then I had these messages when I deployed.
I didn't like the long code repeating and also didn't like the messages so I looked up documentation again... so I wanted to add passHref so that I can get rid of those messages.
https://nextjs.org/docs/messages/link-passhref
import Link from "next/link";
import { StyledLink } from "./styles";
import styled from "styled-components";
const NavLink = ({ href, name }) => {
return (
<Link href={href} passHref>
<StyledLink>{name}</StyledLink>
</Link>
)
}
export default NavLink;
Then I had red lines on href and name and that was because they didn't have types.
So, I added types and imported in NavLink
export interface Links {
href: string,
name: string,
}
I solved problems I had but I wanted to make code simpler and using NavLink, depending on links I wanted to change styling as well. So This is how refactored my code.
NavLink.tsx
import Link from "next/link";
import { StyledLink } from "./styles";
import styled from "styled-components";
import { Links } from "../types/Links";
const StyledLink2 = styled(StyledLink)`
&:hover {
background-color: #2b8aff;
}
`
const NavLink = ({ href, name, bgColor }: Links) => {
if (bgColor === "blue") {
return (
<Link href={href} passHref>
<StyledLink2>{name}</StyledLink2>
</Link>
)
}
return (
<Link href={href} passHref>
<StyledLink>{name}</StyledLink>
</Link>
)
}
export default NavLink;
I wanted to give null value to bgColor for some Links so I added type null in Links
export interface Links {
href: string,
name: string,
bgColor: string | null
}
index.tsx (Beers page directory)
import { Menu, Container } from "../../components/styles";
import NavLink from "../../components/NavLink";
const BeerPage: NextPage = () => {
return (
<div>
<Menu>Beers🍺</Menu>
<Container>
<NavLink href={"/beers/ale"} name={"Ale"} bgColor="blue" />
<NavLink href={"/beers/stouts"} name={"Stouts"} bgColor="blue" />
<NavLink href={"/beers/red-ale"} name={"Red Ale"} bgColor="blue" />
</Container>
</div >
)
}
export default BeerPage;
index.tsx (Wine page directory)
import type { NextPage } from "next";
import { Menu, Container } from "../../components/styles";
import NavLink from "../../components/NavLink";
const WinePage: NextPage = () => {
return (
<div>
<Menu>Wines🍷</Menu>
<Container>
<NavLink href={"/wines/port"} name={"Port"} bgColor={null} />
<NavLink href={"/wines/reds"} name={"Reds"} bgColor={null} />
<NavLink href={"/wines/rose"} name={"Rose"} bgColor={null} />
<NavLink href={"/wines/sparkling"} name={"Sparkling"} bgColor={null} />
<NavLink href={"/wines/whites"} name={"White"} bgColor={null} />
<NavLink href={"/wines/dessert"} name={"Dessert"} bgColor={null} />
</Container>
</div >
)
}
export default WinePage;
I did bgColor="" first and it worked without error but it didn't feel right.. so I changed it to {null} after reading some stuffs on stackoverflow. It said to give either null or undefined value if I wanted to pass empty props.
These are how they look like now.
Wines
Beer
*I might be wrong for some stuff since I am totally new to Typescript and Next.js. Alslo the code will be refactored as well.
Feel free to let me know if you find errors or things that I shouldn't do!
Posted on December 23, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.