# Installing Tailwind CSS and Related ESLint and Prettier Settings - Modern Next.js Blog Series #09

- Canonical: https://easonchang.com/posts/tailwindcss-setup
- Date: 2022-09-24T00:00:00.000Z
- Language: en
- Description: Installing Tailwind CSS, a CSS utility tool, and setting up the corresponding ESLint and Prettier rules
- Translation: AI-assisted, from the zh-TW original

> This article is also published at [it 邦幫忙 2022 iThome Ironman Contest](https://ithelp.ithome.com.tw/articles/10297905)

## TL;DR

This is the 9th article in the "Modern Blog 30 Days" series. In the previous article, we enabled MDX support in Contentlayer. In this article, we will install Tailwind CSS, a CSS utility tool, and set up the corresponding ESLint and Prettier rules, getting ready to beautify our site!

Screenshot of the results:

![Index Page result of Tailwind CSS](https://i.imgur.com/gJiZP1Q.jpg)

The code changes for this article are as follows:

https://github.com/eason-dev/nextjs-tailwind-contentlayer-blog-starter/compare/day08-mdx-support...day09-install-tailwindcss

---

## Installing Tailwind CSS

```shell
pnpm add -D tailwindcss autoprefixer postcss
npx tailwindcss init -p
```

Tweak `/tailwind.config.js`:

```js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ["./src/**/*.{js,ts,jsx,tsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
};
```

Tweak `/postcss.config.js`:

```js
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
};
```

Modify `/src/styles/globals.css` by deleting all its content and replacing it with these three lines:

```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

## Applying Basic Styles to the Homepage to Try Out Tailwind CSS

Remove `/src/styles/Home.module.css`.

Modify `/src/pages/index.tsx` as follows:

```tsx
import type { NextPage } from "next";
import Head from "next/head";

import { allPostsNewToOld, Post } from "@/lib/contentLayerAdapter";

export function getStaticProps() {
  const posts = allPostsNewToOld;
  return { props: { posts } };
}

type Props = {
  posts: Post[];
};

const Home: NextPage<Props> = ({ posts }) => {
  return (
    <div>
      <Head>
        <title>My blog</title>
        <meta name="description" content="Welcome to my blog" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className="p-4">
        <h1 className="mb-6 text-4xl font-bold">Welcome to my blog!</h1>

        <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
          {posts.map((post) => (
            <div key={post.slug} className="rounded-lg border border-black p-6">
              <a href={post.path}>
                <h2 className="mb-4 text-2xl font-semibold">{post.title}</h2>
                <p>{post.description}</p>
              </a>
            </div>
          ))}
        </div>
      </main>
    </div>
  );
};

export default Home;
```

Modify `/src/pages/[slug].tsx` as follows:

```tsx
import { format, parseISO } from "date-fns";
import type { GetStaticPaths, GetStaticProps, NextPage } from "next";
import Head from "next/head";
import { useMDXComponent } from "next-contentlayer/hooks";

import { allPosts, Post } from "@/lib/contentLayerAdapter";

export const getStaticPaths: GetStaticPaths = () => {
  const paths = allPosts.map((post) => post.path);
  return {
    paths,
    fallback: false,
  };
};

export const getStaticProps: GetStaticProps<Props> = ({ params }) => {
  const post = allPosts.find((post) => post.slug === params?.slug);
  if (!post) {
    return {
      notFound: true,
    };
  }
  return {
    props: {
      post,
    },
  };
};

type Props = {
  post: Post;
};

const PostPage: NextPage<Props> = ({ post }) => {
  const MDXContent = useMDXComponent(post.body.code);

  return (
    <div>
      <Head>
        <title>{post.title}</title>
        <meta name="description" content={post.description} />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main>
        <h1>{post.title}</h1>

        <time dateTime={post.date}>
          {format(parseISO(post.date), "LLLL d, yyyy")}
        </time>

        <MDXContent />
      </main>
    </div>
  );
};

export default PostPage;
```

## Installing Tailwind CSS Related ESLint and Prettier Rules

```shell
pnpm add -D eslint-plugin-tailwindcss prettier-plugin-tailwindcss
```

Modify `.prettierrc.js` to add the prettier-plugin-tailwindcss plugin. The final result is as follows:

```js
module.exports = {
  trailingComma: "es5",
  singleQuote: true,
  printWidth: 80,
  semi: true,
  plugins: ["prettier-plugin-tailwindcss"],
};
```

Modify `.eslintrc.js`:

```js
module.exports = {
  extends: [
    "eason",
    "next/core-web-vitals",
    "plugin:tailwindcss/recommended",
    "plugin:prettier/recommended", // Make this the last element so prettier config overrides other formatting rules
  ],
  plugins: ["tailwindcss"],
  rules: {
    "jsx-a11y/anchor-is-valid": [
      "error",
      {
        components: ["Link"],
        specialLink: ["hrefLeft", "hrefRight"],
        aspects: ["invalidHref", "preferButton"],
      },
    ],
    "tailwindcss/classnames-order": "off", // Respect prettier-plugin-tailwindcss order
  },
  settings: {
    // Support absolute imports
    // https://www.npmjs.com/package/eslint-import-resolver-alias
    "import/resolver": {
      alias: {
        map: [["@", "./src"]],
        extensions: [".js", ".jsx", ".ts", ".tsx"],
      },
    },
    "import/ignore": ["contentLayerAdapter.js"],
  },
  overrides: [
    {
      files: "**/*.{ts,tsx}",
      extends: [
        "eason/typescript",
        "plugin:prettier/recommended", // Make this the last element so prettier config overrides other formatting rules
      ],
    },
  ],
};
```

## Results

Done! Run `pnpm dev` and enter the homepage, and you will see the homepage style has changed. All of it is achieved with Tailwind CSS utility classes!

The results are as follows:

![Index Page result of Tailwind CSS](https://i.imgur.com/gJiZP1Q.jpg)

The code changes for this article are as follows:

https://github.com/eason-dev/nextjs-tailwind-contentlayer-blog-starter/compare/day08-mdx-support...day09-install-tailwindcss

## References

https://tailwindcss.com/docs/guides/nextjs

## Next Article

Congratulations! We have successfully installed Tailwind CSS and the corresponding ESLint and Prettier rules in our Next.js project, and given it a quick try.

In the next article, we will add an essential element of a modern blog: dark mode! It is also implemented with Tailwind CSS.

After that, we will start truly beautifying the styles of the entire site!
