Tailwindcss in Styled-Components
Tags: tailwindcss, styledcomponents, nextjs, twinmacro
Published: 2023-04-18 17:08:31

## **Setup A Next JS Project With TailwindCSS and Twin Macro**

> In this blog we will be looking at setting up an Next JS project as quickly and easily as possible.


<br>

## Table of Contents

- [What is Twin macro](#what-is-twin-macro)
- [Why TailwindCSS + Twin Macro](#why-tailwindcss-and-twin-macro)
- [Initial Setup](#project-setup)
- [Packages Required](#packages-required)
- [File Structure + Setup](#file-structure-and-setup)
- [Github Repo and Resources](#github-repo-and-resources)

### What is Twin macro

Twin.macro is a popular library for styling React components using Tailwind CSS. It is built on top of styled-components and provides a set of macros that allow you to write CSS in a more intuitive way, using the same syntax as Tailwind.
Twin Macro is a powerful way to utilize what TailwindCSS has to offer, and maintain clean code by separating the CSS from our code while still keeping it within the relevant files.

### Why TailwindCSS and Twin Macro

> There are two problems when it comes to Tailwind.

1. You must be well-versed in CSS guidelines. However this may be resolved with tonnes of learning, practise, and repetition.

2. You get the same result as inline styles when classes are applied directly to React/HTML elements: a jumbled visual appearance.
  - Twin Macro can help with this. By placing the React/HTML elements into their own constants at the front of our project, this library enables us to segregate the CSS from the React/HTML elements. As a result, our code base will remain organised and we can retain our pertinent styling applied to the React/HTML elements.
  - Also, Twin Macro makes it much easier to add `conditional styles` to our elements, which is a tremendous benefit.

**Example**

```jsx
import tw from 'twin.macro'

const Input = ({ hasHover }) => (
  <input css={[tw`border`, hasHover && tw`hover:border-black`]} />
)
```

## Project Setup

Diving straight into things, let’s open up cmd and cd to where we want to create our new project. Once in your desired directory, we need to create our project via npm. Run the following command to download a Next JS app with tailwind preconfigured. Make sure you replace “my-project” with the desired name of your project.

```javascript
npx create-next-app -e with-tailwindcss my-project
```
Once the files are finished downloading, follow the instructions in the terminal and run:

```javascript
cd my-project
```
If you wish to take a look at the installed boilerplate, feel free to run:

```javascript
npm run dev
```
This will make your downloaded boilerplate viewable at http://localhost:3000.

Open that URL in your browser to take a look if you wish to. Please feel free to take a look at this post as it is right now because we won't be modifying any of the basic design.

### Packages Required

In order to get Twin.macro up and running in our project, we will need to install a few more package dependencies. These are:

- Emotion
- babel
- twin.macro

Some of these will be installed as regular dependencies, and others will be dev dependencies. Back in your cmd, run the following commands:

```javascript
npm install @emotion/react @emotion/styled @emotion/css @emotion/server
```

```javascript
npm install -D twin.macro @emotion/babel-plugin babel-plugin-macros
```

These are all the packages we will be using in our setup.

Open your code editor if you haven't done so already. I'll be working with VS Code. Open your project and verify your `package.json` file. It should seem as follows:

![Dependecies](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xja08qqv7huoyhxoor0a.png)

### File Structure and Setup

To setup, we need to update a few things to our current files and add a few additional files. Let's first open `/pages/ app.js` by navigating there.


![app.js](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ixljk7f36i977bh2othx.png)



Here, we need to import GlobalStyles from twin.macro. This brings in the base styles from Tailwind, and makes it work throughout our app. Copy the code below and replace the code in `/pages/_app.js` with it, and save your file.

```jsx
// page/_app.js
import { GlobalStyles } from 'twin.macro'

const App = ({ Component, pageProps }) => (
  <div>
    <GlobalStyles />
    <Component {...pageProps} />
  </div>
)

export default App
```

Next, we must create a _document.js file within our pages folder. The path for it should be `/pages/_document.js`.

![document.js](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hjdixc6u76qa5ugl5f66.png)

Next JS uses this file to set up certain additional options or do tasks like importing Google fonts. In our situation, we use it to ensure that the styles rendered on the client side and the server side are same. 
Add the following code to your `_document.js` file and then save it.

```jsx
import Document, { Html, Head, Main, NextScript } from 'next/document'
import { extractCritical } from '@emotion/server'

export default class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx)
    const page = await ctx.renderPage()
    const styles = extractCritical(page.html)
    return { ...initialProps, ...page, ...styles }
  }

  render() {
    return (
      <Html lang="en">
        <Head>
          <style
            data-emotion-css={this.props.ids.join(' ')}
            dangerouslySetInnerHTML={{ __html: this.props.css }}
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    )
  }
}

```

The next step is optional, and only needs to be done if you need to tweak the configuration of Twin. Here is the full list of Twin config options. Open up your `package.json` file, and past the following code in:

```cpp
// package.json
"babelMacros": {
  "twin": {
     "preset": "emotion"
  }
},
```
You package.json should look like this now:

![babel](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r9m8mfylmf2k6e1k7jip.png)

Now for the final step in our setup. In the root folder of your project, create a `.babelrc.js` file.

![babelrc](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mqck0tkmnvmjh390wkbj.png)

Open it, paste to following code in and save it.

```
// .babelrc.js
module.exports = {
  presets: [
    [
      'next/babel',
      {
        'preset-react': {
          runtime: 'automatic',
          importSource: '@emotion/react',
        },
      },
    ],
  ],
  plugins: ['@emotion/babel-plugin', 'babel-plugin-macros'],
}
```
Congratulations! 🎉 Your project is now running and functional. You can spin up your server now using npm run dev, and start building out your project!

### Github Repo and Resources

Thank you for following along with this article. I do hope it has helped you start your next project with this fantastic tech stack. Here are a few extra resources which may be helpful.

Wanna know how it works?? Checkout [Codesandbox.](https://codesandbox.io/p/github/Bhanu1776/twin-setup/main?file=%2FREADME.md&workspace=%257B%2522activeFilepath%2522%253A%2522%252Fpages%252Findex.js%2522%252C%2522openFiles%2522%253A%255B%2522%252FREADME.md%2522%255D%252C%2522sidebarPanel%2522%253A%2522EXPLORER%2522%252C%2522gitSidebarPanel%2522%253A%2522COMMIT%2522%252C%2522spaces%2522%253A%257B%2522clgm9zl56000x2v6vxvxev4s8%2522%253A%257B%2522key%2522%253A%2522clgm9zl56000x2v6vxvxev4s8%2522%252C%2522name%2522%253A%2522Default%2522%252C%2522devtools%2522%253A%255B%257B%2522type%2522%253A%2522PREVIEW%2522%252C%2522taskId%2522%253A%2522dev%2522%252C%2522port%2522%253A42411%252C%2522key%2522%253A%2522clgm9zvmm006o2v6v8e96oddu%2522%252C%2522isMinimized%2522%253Afalse%257D%252C%257B%2522type%2522%253A%2522TASK_LOG%2522%252C%2522taskId%2522%253A%2522dev%2522%252C%2522key%2522%253A%2522clgma2ivd00hy2v6vvvksteo0%2522%252C%2522isMinimized%2522%253Afalse%257D%255D%257D%257D%252C%2522currentSpace%2522%253A%2522clgm9zl56000x2v6vxvxev4s8%2522%252C%2522spacesOrder%2522%253A%255B%2522clgm9zl56000x2v6vxvxev4s8%2522%255D%252C%2522hideCodeEditor%2522%253Afalse%257D)

Github Repo of this project. Feel free to clone and use this for your projects.

Navigate to your desired folder location and run the code below in a terminal to get started.

```sh
git clone https://github.com/Bhanu1776/twin-setup
cd next-tw-twin
npm install
```

[Tailwind Docs](https://tailwindcss.com/). This is your go to for anything Tailwind.

[Twin Macro Github Repo](https://github.com/ben-rogerson/twin.macro). This is a great resource to help you pick up Twin’s syntax, learn more about the package, and keep up to date with the latest releases.

[Tailwind Twin IntelliSense](https://marketplace.visualstudio.com/items?itemName=lightyen.tailwindcss-intellisense-twin) is a fantastic extension to use when building a project with Twin + Tailwind. I highly recommend using it as it will make make it much easier to write your code via its Tailwind class suggestions.

**Swc Error**
If you are facing swc compiler error make sure you checkout this [article.](https://blog.mrcatdev.com/how-to-config-nextjs-for-babel-plugin-macros-like-twinmacro-without-disabling-swc-compiler)


## Contact with Me

- [Github](https://github.com/Bhanu1776)
- [LinkedIn](https://www.linkedin.com/feed/)

**If you wondering which vscode theme i've used, Checkout [JellyFish-x-Retro](https://marketplace.visualstudio.com/items?itemName=Bhanu1776.jellyfish-retro)**

I hope this blog has helped you to setup this awesome tech stack. Thanks for reading the blog!