Launch Next.js with TailwindCSS

0 Shares
0
0
0
0

Introduction

This tutorial shows how to install Next.js in combination with TailwindCSS to create an initial setup for various frontend projects.

Next.js is a ReactJS front-end framework that offers many useful features. Not only can it act as a static site generator, but it also has advanced strategies for fetching data from various sources to display dynamic content.

TailwindCSS is a CSS framework that uses a functional-first approach to applying CSS class names. It's an efficient way to create modern layouts and designs without having to worry about naming conventions.

Prerequisites
  • System with MacOS, Windows or Linux
  • The latest version of Node.js and npm are installed.

Step 1 – Install Next.js

You can install Next.js automatically or manually.

  • Automatically:
npx create-next-app my-project [--use-npm]
  • Manually:
mkdir ~/my-project && cd ~/my-project
npm install next react react-dom

After installing Next.js, edit the new file ~/my-project/package.json and add the “script” section as shown here:

{
"dependencies": {
<your_dependencies>
},
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
}
}

Step 2 – Install TailwindCSS

TailwindCSS uses PostCSS as a preprocessor and AutoPrefix as additional dependencies. This is optional but recommended, as Tailwind offers some nice features when using these plugins, e.g. using non-standard keywords like @apply, @theme or theme() which can be used in our custom CSS file.

cd ~/my-project
npm install -D tailwindcss postcss autoprefixer

After that, we can create a configuration file for TailwindCSS:

npx tailwindcss init -p

This will create tailwind.config.js and postcss.config.js.

Step 3 – Configure Next.js

To define routes for our application, we can simply add additional JavaScript files to the application directory. In this tutorial, we will focus on pages that are not dynamically generated. This is because in many cases it is necessary to generate routes using dynamic data, for example, creating routes based on an ID. You can find a great guide on how to achieve this in the Next.js documentation (make sure the menu is set to "Use Application Router").

Add pages

To create pages, you need a subdirectory called app. Inside the app, you need two files:

FileDescription
app/layout.tsxThis file contains information about the layout that is automatically applied to all pages including the main page and all subpages.
app/page.tsxThis contains the content for the main page.

Additionally, you can add as many subdirectories as you want. Each subdirectory, with a page.tsx file, represents a subpage for your application.

In this tutorial we will use the following example:

app/
├── layout.tsx # layout of main page and all subpages
├── page.tsx # content main page
└── example-subpage/
├── layout.tsx # additional layout requirements for example-subpage
└── page.tsx # content example-subpage

This example gives us two pages:

http://<ip-address>:3000 # main page
http://<ip-address>:3000/example-subpage # subpage

If you installed Next.js manually, create the application files directory:

mkdir ~/my-project/app

Now you can add content to your pages:

  • Home page
nano ~/my-project/app/page.tsx

Use this content for the home page:

// ~/my-project/app/page.tsx
export default function Page() {
return <h1 className="text-white text-3xl font-bold pl-5">Welcome to Next.js and TailwindCSS</h1>
}
  • Subpage

Add a new subdirectory for the subpage and create page.tsx:

mkdir ~/my-project/app/example-subpage
nano ~/my-project/app/example-subpage/page.tsx

Use this content for the subpage:

// ~/my-project/app/example-subpage/page.tsx
export default function Page () {
return (
<>
<div className="flex flex-col place-content-center items-center col-span-1 pr-3">
<div className="border-2 rounded-full p-0.5 border-gray-600 mb-2">
<img
className="rounded-full w-100 h-100"
src="https://picsum.photos/100/100"
alt="random image from unsplash"
/>
</div>
</div>
<div className="col-span-5 pr-3">
<h2 className="text-white text-3xl font-semibold pl-4 mb-3">Welcome to Next.js and TailwindCSS</h2>
<span className="text-gray-500 text-lg font-bold block pl-4 mb-3">Bringing both frameworks together</span>
<p className="text-white pl-4 leading-7">
Cats are believed to be the only mammals who don't taste sweetness. Cats are nearsighted, but their peripheral
vision and night vision are much better than that of humans. Cats are supposed to have 18 toes (five toes on
each front paw; four toes on each back paw). Cats can jump up to six times their length.
</p>
</div>
</>
)
}

Add layout (TailwindCSS)

Now that we have the content of our pages, we can add the layout in which the pages should be displayed.

  • General layout for the home page and all subpages

As mentioned earlier, the layout defined in app/layout.js is automatically applied to the main page and all subpages.

Choose one of these two options to include TailwindCSS:

  • Alternative 1: Via JavaScript

This is a convenient way to add TailwindCSS without having to write any additional stylesheets.

nano ~/my-project/app/layout.tsx

Use this content:

// ~/my-project/app/layout.tsx
import 'tailwindcss/tailwind.css'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<>
<html lang="en">
<head>
<title>Next.js and TailwindCSS</title>
<link rel="icon" href="/favicon.ico"/>
</head>
<body className="min-h-screen bg-gradient-to-tr from-midnight-100 via-midnight-200 to-midnight-300 flex flex-col justify-center">{children}</body>
</html>
</>
)
}
  • Alternative 2: Via CSS

Another option is to add Tailwind styles using CSS. To achieve this, we import the global stylesheet into the app/layout.tsx file.

Create app/layout.tsx:

nano ~/my-project/app/layout.tsx

Use this content:

// ~/my-project/app/layout.tsx
import './globals.css'
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<>
<html lang="en">
<head>
<title>Next.js and TailwindCSS</title>
<link rel="icon" href="/favicon.ico"/>
</head>
<body className="min-h-screen bg-gradient-to-tr from-midnight-100 via-midnight-200 to-midnight-300 flex flex-col justify-center">{children}</body>
</html>
</>
)
}

Create the global sheet app/global.css:

/* ~/my-project/app/globals.css */
@tailwind base;
@tailwind components;
@tailwind utilities;

Unfortunately, Tailwind doesn't provide an in-depth explanation of what the @tailwind directive does, other than injecting generated styles (based on Tailwind's configuration) into the stylesheet at build time.

  • Custom layout for subpages

Each subpage has its own layout file. When you have additional layout needs, you can save them directly in the subpage layout file or save them in a dedicated directory and import it into the subpage layout file. Saving additional layout specifications in a dedicated directory makes it easier to reuse the layout across multiple subpages. So it makes sense if you need the same layout for multiple subpages.

Create a directory for additional layouts:

mkdir ~/my-project/components

Create additional layout:

nano ~/my-project/components/FancyCard.js

Add this content:

// ~/my-project/components/FancyCard.js
'use client'
import React from 'react'
const FancyCard = ({ children }) => {
return (
<div className="max-w-xl mx-auto">
<div className="p-8 bg-midnight-200 shadow-xl rounded-3xl border-4 border-gray-600">
<div className="grid grid-cols-6 gap-0 divide-x divide-gray-600">
{children}
</div>
</div>
</div>
)
}
export default FancyCard

Now create the layout.tsx file for your subpage and apply additional layout specifications:

nano ~/my-project/app/example-subpage/layout.tsx
// ~/my-project/app/example-subpage/layout.tsx
import FancyCard from '../../components/FancyCard'
export default function Layout({ children }) {
return <FancyCard>{children}</FancyCard>
}

As mentioned earlier, you can add more layouts to components as needed and include them in the layout.tsx file of each subpage that should use that particular layout, as shown above. If you plan to use a layout only once, you can add it directly in the layout.tsx file of that subpage.

Step 4 – Configure TailwindCSS

The final step is to customize the configuration files for Tailwind and PostCSS.

By running npx tailwindcss init -p we have already created two configuration files:

  • tailwind.config.js
  • postcss.config.js

If we want to use PostCSS as a preprocessor, we can use postcss.config.js for additional functions such as adding vendor prefixes, adding global CSS resets, or creating @font-face rules.

Another great feature in TailwindCSS is that you can easily customize the default theme. By changing the theme property in tailwind.config.js, we can make customizations, e.g. custom breakpoints, colors, fonts, or more detailed features, such as spacing, border radius, or box shadows. By changing the color key, we can add our own custom color palette to the existing theme:

nano ~/my-project/tailwind.config.js

Add the following content:

// ~/my-project/tailwind.config.js
const defaultTheme = require('tailwindcss/defaultTheme')
module.exports = {
content: [
'./app/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}',
],
theme: {
colors: {
...defaultTheme.colors,
'white': '#ffffff',
'black': '#242424',
'midnight': {
'100': '#03060a',
'200': '#001a40',
'300': '#060b17',
// add more color variants if you want to
},
'gray': {
'500': '#6b7280',
'600': '#4b5563',
},
'purple': {
'500': '#6d28d9',
},
// add more colors if you want to
},
},
plugins: [],
}

Additionally, we are extending the default color scheme, so we can still use Tailwind's default color palette. Notice that we can now apply our own colors to multiple application classes using the defined color and its corresponding variant, bg-{color}-{variant}. For example:

<div className="bg-midnight-300">
...
</div>

Step 5 – Start the app

Now that everything is set up, we can run the program to see our result:

  • To access via private IP (localhost):
npm run dev
  • To access via public IP:
npm run dev -- -H 0.0.0.0

Open both pages in a web browser:

http://<ip-address>:3000http

://<ip-address>:3000/example-subpage

This should look like this:

Result

We successfully launched a Next.js application that uses Tailwind as a CSS framework.

The use of CSS frameworks for the first time creates a lot of controversy and as usual there is no universal rule. Some say that it is messy and hard to read, that it is no different from inline styles or that it violates separation of concerns. Personally, I think that all of these points can be argued against and I recommend the following two articles to get a feel for both sides. That way you will get a feel for whether this framework is right for your next project.

Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like