How to design a simple and beautiful Navbar using NextJS and TailwindCSS
Tags: react, programming, nextjs, javascript
Published: 2020-12-24 18:47:07

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4e0ovzdkh14ciz4yko3n.jpg)
Definitely NextJS has positioned itself as the best React framework at present, offering all the benefits of the library we love so much, in addition to offering extras such as SSR and configuration for SEO. 

So, the purpose of this post is to show how easy and intuitive it can be to make a navbar in NextJS with the help of TailwindCSS. For more complexity, I will make a second post in which we will add a global status for the elements of our Navbar to change. 

#Setup and configuration

So, the first thing that we need is install NextJS with NextCli, in my case I prefer to use Yarn.

```
yarn create next-app
```
After creating our application, we proceed to install tailwind and the dependencies we need:

```
yarn add tailwindcss@latest postcss@latest autoprefixer@latest postcss-cli
```

After installing our dependencias, we need to do some modifications in App.js and create new files. Let's start by creating the file postcss.config.js , which will be located in the root of the project:

```
touch postcss.config.js
```
Inside the file, we will place the following configuration
```javascript
// postcss.config.js
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}
```
After this, we will create the file tailwind.config.js with the following command

```
npx tailwindcss init --full
```
This generates a tailwind.config.js file that we can modify and custom like we want.

Now, we can delete the default generate style created by Next and we need to create two files in the styles folder: main.css and tailwind.css.

Inside the tailwind.css file we need to add this content

```css
/* ./styles/tailwind.css */
@tailwind base;
@tailwind components;
@tailwind utilities;
```
After that we must modify the App.js and Index.js pages so that they do not conflict with the deleted files.

```javascript
/* ./pages/index.js               */
import Head from 'next/head';

export default function Home() {
  return (
    <div>
      <Head>
        <title>Create Next App</title>
        <link rel='icon' href='/favicon.ico' />
      </Head>
      <div>Hello World</div>
    </div>
  );
}
```

```javascript
/*   ./styles/_app.js              */
import '../styles/main.css';

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} />;
}

export default MyApp;
```

So, before we can work with Tailwind in our Next App, we need to generate a script that compiles the Tailwind classes in our main.css file. Therefore, in the package.json we need to add some scripts

```json
{
  "name": "ourapp",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "build:css": "postcss styles/tailwind.css -o styles/main.css",
    "build:watch": "postcss styles/tailwind.css -o styles/main.css --watch",
    "prod:build": "NODE_ENV=production yarn run build:css && yarn run build"
  },
  "dependencies": {
    "autoprefixer": "^10.1.0",
    "next": "10.0.4",
    "postcss": "^8.2.1",
    "postcss-cli": "^8.3.1",
    "react": "17.0.1",
    "react-dom": "17.0.1",
    "tailwindcss": "^2.0.2"
  }
}
```

Finally, we need to execute build:css
```
yarn build:css
```
And now we can use Tailwind in all out application :D . 


#Create the directory
Before we start, I'd like to show you the architecture I prefer to use in this type of application 
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/6k446isgs52l9cdfl82h.png)

And now we need to insert our component in the Layout. In this case we don't create a layout container, so we add the component directly in Index.js. 

```react
/* ./pages/index.js               */
import Head from 'next/head';
import { Navbar } from '../components/Navbar';

export default function Home() {
  return (
    <div>
      <Head>
        <title>Create Next App</title>
        <link rel='icon' href='/favicon.ico' />
      </Head>
      <Navbar />
      <div>Hello World</div>
    </div>
  );
}

```


#Start our component
```react
/*  ./components/Navbar.jsx     */

export const Navbar = () => {
  return (
    <div>
      
    </div>
  )
}
```
From the 17 React version it's no neccesary to import react in our functional components. 

We will start by defining the grid which in this case will be flex, the padding and the background color

```react
/*  ./components/Navbar.jsx     */

export const Navbar = () => {
  return (
    <>
      <nav className='flex items-center flex-wrap bg-green-300 p-3 '></nav>
    </>
  );
};

```

Next offers us its beautiful and useful tool Link for the redirection inside our SPA, so in this case we will use it for the logo and it will redirect us to the "Home" or main view of our application. 

```react
/*  ./components/Navbar.jsx     */
import Link from 'next/link';

export const Navbar = () => {
  return (
    <>
      <nav className='flex items-center flex-wrap bg-green-300 p-3 '>
        <Link href='/'>
          <a className='inline-flex items-center p-2 mr-4 '>
            <svg
              viewBox='0 0 24 24'
              xmlns='http://www.w3.org/2000/svg'
              className='fill-current text-white h-8 w-8 mr-2'
            >
              <path d='M12.001 4.8c-3.2 0-5.2 1.6-6 4.8 1.2-1.6 2.6-2.2 4.2-1.8.913.228 1.565.89 2.288 1.624C13.666 10.618 15.027 12 18.001 12c3.2 0 5.2-1.6 6-4.8-1.2 1.6-2.6 2.2-4.2 1.8-.913-.228-1.565-.89-2.288-1.624C16.337 6.182 14.976 4.8 12.001 4.8zm-6 7.2c-3.2 0-5.2 1.6-6 4.8 1.2-1.6 2.6-2.2 4.2-1.8.913.228 1.565.89 2.288 1.624 1.177 1.194 2.538 2.576 5.512 2.576 3.2 0 5.2-1.6 6-4.8-1.2 1.6-2.6 2.2-4.2 1.8-.913-.228-1.565-.89-2.288-1.624C10.337 13.382 8.976 12 6.001 12z' />
            </svg>
            <span className='text-xl text-white font-bold uppercase tracking-wide'>
              TalwindCSS
            </span>
          </a>
        </Link>
      </nav>
    </>
  );
};
```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/puys4dc0mdosiui17wrn.jpeg)

For now we have a simple view. Now we will proceed to add the hamburger menu that will be seen in smartphones and tablets:

```react
/*  ./components/Navbar.jsx     */
import Link from 'next/link';

export const Navbar = () => {
  return (
    <>
      <nav className='flex items-center flex-wrap bg-green-300 p-3 '>
        <Link href='/'>
          <a className='inline-flex items-center p-2 mr-4 '>
            <svg
              viewBox='0 0 24 24'
              xmlns='http://www.w3.org/2000/svg'
              className='fill-current text-white h-8 w-8 mr-2'
            >
              <path d='M12.001 4.8c-3.2 0-5.2 1.6-6 4.8 1.2-1.6 2.6-2.2 4.2-1.8.913.228 1.565.89 2.288 1.624C13.666 10.618 15.027 12 18.001 12c3.2 0 5.2-1.6 6-4.8-1.2 1.6-2.6 2.2-4.2 1.8-.913-.228-1.565-.89-2.288-1.624C16.337 6.182 14.976 4.8 12.001 4.8zm-6 7.2c-3.2 0-5.2 1.6-6 4.8 1.2-1.6 2.6-2.2 4.2-1.8.913.228 1.565.89 2.288 1.624 1.177 1.194 2.538 2.576 5.512 2.576 3.2 0 5.2-1.6 6-4.8-1.2 1.6-2.6 2.2-4.2 1.8-.913-.228-1.565-.89-2.288-1.624C10.337 13.382 8.976 12 6.001 12z' />
            </svg>
            <span className='text-xl text-white font-bold uppercase tracking-wide'>
              Talwind CSS
            </span>
          </a>
        </Link>
        <button className=' inline-flex p-3 hover:bg-green-600 rounded lg:hidden text-white ml-auto hover:text-white outline-none'>
          <svg
            className='w-6 h-6'
            fill='none'
            stroke='currentColor'
            viewBox='0 0 24 24'
            xmlns='http://www.w3.org/2000/svg'
          >
            <path
              strokeLinecap='round'
              strokeLinejoin='round'
              strokeWidth={2}
              d='M4 6h16M4 12h16M4 18h16'
            />
          </svg>
        </button>
      </nav>
    </>
  );
};
```


![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/folddrukp1p08f0w5m9l.jpeg)

Excellent, now we will proceed to add the view to be had in computers:

```react
/*  ./components/Navbar.jsx     */
import Link from 'next/link';

export const Navbar = () => {
  return (
    <>
      <nav className='flex items-center flex-wrap bg-green-400 p-3 '>
        <Link href='/'>
          <a className='inline-flex items-center p-2 mr-4 '>
            <svg
              viewBox='0 0 24 24'
              xmlns='http://www.w3.org/2000/svg'
              className='fill-current text-white h-8 w-8 mr-2'
            >
              <path d='M12.001 4.8c-3.2 0-5.2 1.6-6 4.8 1.2-1.6 2.6-2.2 4.2-1.8.913.228 1.565.89 2.288 1.624C13.666 10.618 15.027 12 18.001 12c3.2 0 5.2-1.6 6-4.8-1.2 1.6-2.6 2.2-4.2 1.8-.913-.228-1.565-.89-2.288-1.624C16.337 6.182 14.976 4.8 12.001 4.8zm-6 7.2c-3.2 0-5.2 1.6-6 4.8 1.2-1.6 2.6-2.2 4.2-1.8.913.228 1.565.89 2.288 1.624 1.177 1.194 2.538 2.576 5.512 2.576 3.2 0 5.2-1.6 6-4.8-1.2 1.6-2.6 2.2-4.2 1.8-.913-.228-1.565-.89-2.288-1.624C10.337 13.382 8.976 12 6.001 12z' />
            </svg>
            <span className='text-xl text-white font-bold uppercase tracking-wide'>
              Talwind CSS
            </span>
          </a>
        </Link>
        <button className=' inline-flex p-3 hover:bg-green-600 rounded lg:hidden text-white ml-auto hover:text-white outline-none'>
          <svg
            className='w-6 h-6'
            fill='none'
            stroke='currentColor'
            viewBox='0 0 24 24'
            xmlns='http://www.w3.org/2000/svg'
          >
            <path
              strokeLinecap='round'
              strokeLinejoin='round'
              strokeWidth={2}
              d='M4 6h16M4 12h16M4 18h16'
            />
          </svg>
        </button>
        <div className='hidden w-full lg:inline-flex lg:flex-grow lg:w-auto'>
          <div className='lg:inline-flex lg:flex-row lg:ml-auto lg:w-auto w-full lg:items-center items-start  flex flex-col lg:h-auto'>
            <Link href='/'>
              <a className='lg:inline-flex lg:w-auto w-full px-3 py-2 rounded text-white font-bold items-center justify-center hover:bg-green-600 hover:text-white '>
                Home
              </a>
            </Link>
            <Link href='/'>
              <a className='lg:inline-flex lg:w-auto w-full px-3 py-2 rounded text-white font-bold items-center justify-center hover:bg-green-600 hover:text-white'>
                Services
              </a>
            </Link>
            <Link href='/'>
              <a className='lg:inline-flex lg:w-auto w-full px-3 py-2 rounded text-white font-bold items-center justify-center hover:bg-green-600 hover:text-white'>
                About us
              </a>
            </Link>
            <Link href='/'>
              <a className='lg:inline-flex lg:w-auto w-full px-3 py-2 rounded text-white font-bold items-center justify-center hover:bg-green-600 hover:text-white'>
                Contact us
              </a>
            </Link>
          </div>
        </div>
      </nav>
    </>
  );
};

```
So, now we hace the deskopt view:
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/4jx1g4slhwbgxtnbby16.jpeg)

After of this, we need a function that shows or hidden the menu when we click in the hamburger menu. For this we create a state using the useState hook and a function for the button when we click on it: 

```react
/*  ./components/Navbar.jsx     */
import Link from 'next/link';
import { useState } from 'react';

export const Navbar = () => {
  const [active, setActive] = useState(false);

  const handleClick = () => {
    setActive(!active);
  };

  return (
    <>
      <nav className='flex items-center flex-wrap bg-green-400 p-3 '>
        <Link href='/'>
          <a className='inline-flex items-center p-2 mr-4 '>
            <svg
              viewBox='0 0 24 24'
              xmlns='http://www.w3.org/2000/svg'
              className='fill-current text-white h-8 w-8 mr-2'
            >
              <path d='M12.001 4.8c-3.2 0-5.2 1.6-6 4.8 1.2-1.6 2.6-2.2 4.2-1.8.913.228 1.565.89 2.288 1.624C13.666 10.618 15.027 12 18.001 12c3.2 0 5.2-1.6 6-4.8-1.2 1.6-2.6 2.2-4.2 1.8-.913-.228-1.565-.89-2.288-1.624C16.337 6.182 14.976 4.8 12.001 4.8zm-6 7.2c-3.2 0-5.2 1.6-6 4.8 1.2-1.6 2.6-2.2 4.2-1.8.913.228 1.565.89 2.288 1.624 1.177 1.194 2.538 2.576 5.512 2.576 3.2 0 5.2-1.6 6-4.8-1.2 1.6-2.6 2.2-4.2 1.8-.913-.228-1.565-.89-2.288-1.624C10.337 13.382 8.976 12 6.001 12z' />
            </svg>
            <span className='text-xl text-white font-bold uppercase tracking-wide'>
              Talwind CSS
            </span>
          </a>
        </Link>
        <button
          className=' inline-flex p-3 hover:bg-green-600 rounded lg:hidden text-white ml-auto hover:text-white outline-none'
          onClick={handleClick}
        >
          <svg
            className='w-6 h-6'
            fill='none'
            stroke='currentColor'
            viewBox='0 0 24 24'
            xmlns='http://www.w3.org/2000/svg'
          >
            <path
              strokeLinecap='round'
              strokeLinejoin='round'
              strokeWidth={2}
              d='M4 6h16M4 12h16M4 18h16'
            />
          </svg>
        </button>
        {/*Note that in this div we will use a ternary operator to decide whether or not to display the content of the div  */}
        <div
          className={`${
            active ? '' : 'hidden'
          }   w-full lg:inline-flex lg:flex-grow lg:w-auto`}
        >
          <div className='lg:inline-flex lg:flex-row lg:ml-auto lg:w-auto w-full lg:items-center items-start  flex flex-col lg:h-auto'>
            <Link href='/'>
              <a className='lg:inline-flex lg:w-auto w-full px-3 py-2 rounded text-white font-bold items-center justify-center hover:bg-green-600 hover:text-white '>
                Home
              </a>
            </Link>
            <Link href='/'>
              <a className='lg:inline-flex lg:w-auto w-full px-3 py-2 rounded text-white font-bold items-center justify-center hover:bg-green-600 hover:text-white'>
                Services
              </a>
            </Link>
            <Link href='/'>
              <a className='lg:inline-flex lg:w-auto w-full px-3 py-2 rounded text-white font-bold items-center justify-center hover:bg-green-600 hover:text-white'>
                About us
              </a>
            </Link>
            <Link href='/'>
              <a className='lg:inline-flex lg:w-auto w-full px-3 py-2 rounded text-white font-bold items-center justify-center hover:bg-green-600 hover:text-white'>
                Contact us
              </a>
            </Link>
          </div>
        </div>
      </nav>
    </>
  );
};

```
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ymp8t62pod6k65hq5age.jpeg)

And that it's all. Now we have our beatufil and simple Navbar using NextJS and TailwindCSS. 

I recommend a lot that you visit the documentation of *Tailwind* and *Next*. 

[NextJS](https://nextjs.org/)
[TailwindCSS](https://tailwindcss.com/)

Both are powerful frameworks with great documentation that will allow us to stand out more and learn every day to improve as developers. 
I hope to write the second part of this article soon, where with the help of useContext we will add a user section and change the navbar view depending if the user is logged in or not. 

Plus: If you love React and you're looking for a simple and beautiful icons definitively you'll love HeroIcons. Here I let you their official page :D 

[HeroIcons](https://heroicons.dev/)

Merry Christmas and enjoy with your families.