JWJames Wallis
Cover for Using Tailwind CSS, Google Fonts and React-icons with a Next.js application

Using Tailwind CSS, Google Fonts and React-icons with a Next.js application

27th July 2020

This blog is part of a series where I document rebuilding a website that relies on HTML, CSS and Bootstrap in React.js using the Next.js framework to improve performance, reduce costs and increase my workflow for future changes.

The finished website: https://wallisconsultancy.co.uk The source code: https://github.com/james-wallis/wallisconsultancy

As discussed in the previous blog, this project will use Next.js and Tailwind CSS and will be based on the with-tailwindcss example that is supplied by the Next.js team.

In this blog I will:

  1. Use create-next-app to create and setup a Next.js application with Tailwind CSS
  2. Add a Google Font to a Next.js application using a custom document
  3. Add Font Awesome icons through React-icons
  4. Create a React component and style it using Tailwind CSS. It will be styled to look identical to wallisconsultancy.co.uk website shown below

The current Wallis Consultancy website The current Wallis Consultancy website

Creating a Next.js application with Tailwind CSS

Creating a Next.js application couldn't be easier as they have a wide range of starter apps available through their create-next-app utility. This project uses the with-tailwindcss as its base. These are the steps I took to setup and run the starter app:

  1. Run npx create-next-app --example with-tailwindcss wallisconsultancy
  2. Install the required packages cd wallisconsultancy && npm install
  3. Run npm run dev to start the development server
  4. Open http://localhost:3000 in a browser to see the example running

Alt Text

That’s it, we now have a running Next.js application and can use the Tailwind CSS styles without having to do any configuration thanks to the example Next.js provides.

Adding a Google font to Next.js

The current Wallis Consultancy website uses the "Open Sans" font that is available from Google Fonts. It needs to be added to the Next.js application to ensure that the website keeps the same appearance.

Next.js exposes a Head component which can be added to a page to modify the head HTML tag on an individual basis. The font is required to be available throughout the website so instead of adding a Head to every page we can utilise a custom _document.js and only add the Google Font into the Head in a single place.

import Document, {
  Html, Head, Main, NextScript,
} from 'next/document';

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx);
    return { ...initialProps };
  }

  render() {
    return (
      <Html lang="en">
        <Head>
          <link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400&display=swap" rel="stylesheet" />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;

Adding react-icons

In addition to the Next.js and Google Font setup I also need to add React Icons which includes Font Awesome for the various icons used on the page to the website.

To add react-icons to the project I ran npm install -s react-icons - React Icons provides the ability to use ES6 imports to include icons such as Font Awesome.

To use the Thumbs Up icon you would add the following:

// Import
import { FaThumbsUp } from 'react-icons/fa';

// Usage
<FaThumbsUp />

Building a Component that uses Tailwind CSS

Note: Before beginning development I deleted the content from the index.js file in the pages directory and cleared out the components directory. So I had an index.js page that looks like

export default function IndexPage() {
  return (
    <></>
  )
}

Now that the project is setup the first component can be created based on the Wallis Consultancy website.

I split the current website up into sections to represent the different components that I would be building, they are not the final components as sections such as the contact form can be split into the contact me and send me a message components, but they give me a good overview to get started.

Wallis Consultancy split up into components Splitting the website into components

For this blog, I’ll only document my process creating the social icon bar at the top of the page in React using Tailwind CSS to avoid being overly repetitive. The source code for the other components can be viewed on Github.

Social Icon Component

I split the social icon component into three further sections:

  1. Call Me
  2. Email
  3. Social icons (currently only Linkedin)

Important style aspects to recreate:

  • Background colour is #fbfbfb
  • Font colour is #999
  • Font used is Open Sans - Can get this from Google fonts
  • Border bottom is 1px solid #e9e9e9
  • Icons used are from Font Awesome and are
    • Phone - fa-phone
    • Email - fa-envelope
    • LinkedIn - fa-linkedin - has a border: 2px solid #999 and full border-radius

Finished Social Bar The Finished Social Bar

Looks pretty similar! It is only a simple component so the code is simple too - and with Tailwind CSS there are no complex classes to match with elements.

The next two snippets show the minimal effort required to style a component using Tailwind CSS, note the className attribute given to the div in the SocialBar component and the a and p tags in the Email component.

SocialBar.js:

import Phone from './phone'
import Email from './email'
import SocialIcons from './socialIcons'

export default function SocialBar() {
  return (
    // bg-gray-fb === Background-color defined in Tailwind config
    // w-screen === width: 100vw;
    // font-open-sans === Custom font defined in Tailwind Config
    <div
      className="bg-gray-fb flex items-center w-screen justify-between px-8 text-gray-999 text-sm font-open-sans border-b border-gray-e9"
    >
      <div className="flex">
        <Phone />
        <Email />
      </div>
      <div>
        <SocialIcons />
      </div>
    </div>
  )
}

Email.js:

// The Font Awesome Envelope Icon
import { FaEnvelope } from 'react-icons/fa';

export default function Email() {
  return (
    // flex === display: flex;
    // items-center === align-items: center;
    // m-2 === margin: 0.5rem;
    <a href="mailto:mw@wallisconsultancy.co.uk"
className="flex items-center m-2">
      <FaEnvelope />
      // ml-2 === margin-left: 0.5rem;
      <p className="ml-2">
        Email: mw@wallisconsultancy.co.uk
      </p>
    </a>
  )
}

You can see in the snippets a few custom classes that are defined in my tailwind.config.js such as the font-gray-999.

module.exports = {
  purge: ['./components/**/*.{js,ts,jsx,tsx}', './pages/**/*.{js,ts,jsx,tsx}'],
  theme: {
    extend: {
      textColor: {
        'gray-999': '#999',
      },
      backgroundColor: {
        // Shown in the SocialBar component as bg-gray-fb
        'gray-fb': '#fbfbfb',
      },
      borderColor: {
        'gray-e9': '#e9e9e9',
        'gray-999': '#999',
      },
      fontFamily: {
        // Shown in the SocialBar component as font-open-sans
        'open-sans': '"Open Sans", Helvetica, Arial, sans-serif',
      },
    },
  },
  variants: {},
  plugins: [],
}

The other components were implemented in the same way and can be seen on Github.

Round up

In this blog I’ve shown how to setup a Next.js application with Tailwind CSS, Google Fonts and React-icons. I provided two example components demonstrating how they can be used together.

I highly recommend you try out the with-tailwindcss example from Next.js as it provides a nice introduction to both frameworks.

In the next blog in this series I’ll be using EmailJS to power the contact form to remove the requirement for a backend server.

React, comment and follow on