Errors I dealt with in Next.js - styled components, pages, types
Tags: nextjs, styledcomponents, typescript, beginners
Published: 2021-12-23 14:53:32

# 1. Warning : Props 'className' did not match Server: ' ' Client: ' '

I wanted to add styled components so I installed styled-components
```js
yarn add styled-components
```
and added this code below in package.json
```js
  "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.
```ts
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`** 
```js
yarn add --dev @types/styled-components babel-plugin-styled-components
```
and added **`babelrc`** in the root of project directory. Then added this code below
```js
{
    "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. 
![error-msg](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f8g5l8s46aji9wr0dphx.png)
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.
![error3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rfon6x6at75bajd1y0en.png)
I used **`<a>`** tags to link pages and had this problem. So I checked Next.js documentation and added Links like this way

```js
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.
![msgs](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/imb4qbo6zls82akr7z8c.png)
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
```ts
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
```ts
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
```ts
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

```ts
export interface Links {
    href: string,
    name: string,
    bgColor: string | null
}
```


### index.tsx (Beers page directory)
```ts
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)
```ts
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](https://wine-likelion-com-da.vercel.app/wines)
[Beer](https://wine-likelion-com-da.vercel.app/beers)


*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!