Let's build Advice Generator App using React.js & Tailwind CSS.
Tags: react, nextjs, tailwindcss
Published: 2022-05-29 08:40:27

---
title: Let's build Advice Generator App using React.js & Tailwind CSS.
published: true
date: 2022-05-16 02:12:00 UTC
tags: Reactjs , Nextjs, Tailwindcss
canonical_url: https://nextjsdev.com/lets-build-advice-generator-app-using-react-js-tailwind-css/
---

 ![Let's build Advice Generator App using React.js & Tailwind CSS.](https://nextjsdev.com/content/images/2022/04/reactjs-image-2.PNG)

Hello everyone,  I hope you all are doing well.  I am back with another exciting web dev project, which will help to learn some new web dev skills as a Front-end developer.

In this tutorial, I will show you how you can build an Advice Generator App, It's one of the  Frontend Mentor challenge projects and our goal is to make it look like the design given by the Frontend Mentor.

Here is the link to the [FrontendMentor](https://www.frontendmentor.io/challenges/advice-generator-app-QdUG-13db) challenge that we will build.

So without any further talk, Let's start building it 🚀.

[🚀 Live Demo of the Project](https://advice-generator-app-raivikas.vercel.app/)


## Step-1 Initializing the Project


Create a new next-js app with Tailwind CSS bootstrapped in it.

You can use this one-line command to create a new nextjs app with TypeScript and Tailwind CSS.

<!--kg-card-begin: markdown-->
```bash
npx create-next-app -e with-tailwindcss my-project-name

```
<!--kg-card-end: markdown-->

You can name your project whatever you want, I will name it an **Advice Generator App.**

>💡 We are using TypeScript in this Project, so we have to explicitly define all the props, constants & function data types.

Now after creating the project open it in Vs Code or any IDE that you prefer.

Find the **index.tsx** file inside **pages** directory. and delete everything and paste the given code below.

<!--kg-card-begin: markdown-->
```jsx
import type { NextPage } from 'next'
import Head from 'next/head'

const API="https://api.adviceslip.com/advice";

const Home: NextPage = () => {

return (
    <div className="flex min-h-screen flex-col items-center bg-[#1e1f29]">
      <Head>
        <title>Advice Generator App</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>

)}

export default Home;

```
<!--kg-card-end: markdown-->

In this project we are using **Manrope** font, so for that, we need to import this font from google fonts.

And for the API part, we are going to use **Advice Slip API** , which is a free API.

As you can see in the above code we have added a constant name API with the value of the API link

After that visit the **globals.css** file inside the **styles** folder and import a google font link (Manrope Font) at the top of the file inside it.

<!--kg-card-begin: markdown-->
```css
@import url('https://fonts.googleapis.com/css2?family=Manrope:wght@600;700&display=swap');

@tailwind base;
@tailwind components;
@tailwind utilities;

```
<!--kg-card-end: markdown-->

So, now to use the font inside our app, we need to add it as a  custom font inside the **tailwindcss.config.js** file.

<!--kg-card-begin: markdown-->
```js
module.exports = {
  content: [
    './pages/**/*.{js,ts,jsx,tsx}',
    './components/**/*.{js,ts,jsx,tsx}',
  ],
  theme: {
    extend: {
      fontFamily:{
        manrope:["Manrope"],
      }
    },
  },
  plugins: [],
}

```
<!--kg-card-end: markdown-->

## Step-2  Creating the Components

If you see the design given by the Frontend Mentor Challenge, there are only two components that you can make.

1. AdviceCard.tsx
2. CircularButton.tsx

So, now create the components folder inside your project folder and create two files with the names **AdviceCard.tsx** and **CircularButton.tsx**.

First, we will create the **CircularButton** component and then the **AdviceCard** component.

**Inside CircularButton.tsx**

<!--kg-card-begin: markdown-->
```jsx
import React from 'react'

interface Prop {
    handleAdvice():void,
}

export const CircularButton = ({handleAdvice} : Prop) => {
    return (
        <button onClick={handleAdvice} className=" bg-emerald-400 px-4 py-4 rounded-full text-green-900 hover:bg-green-200 hover:text-emerald-500 hover:shadow-xl hover:shadow-emerald-600 hover:scale-105 transition duration-300 ease-in">
            <svg xmlns="http://www.w3.org/2000/svg" className="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="3">
                <path strokeLinecap="round" strokeLinejoin="round" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
            </svg>
        </button>
    )
}

```
<!--kg-card-end: markdown-->

In the above code as you can see we have added a prop **handleAdvice** , which is a function that will fetch new Advice data every time the button gets clicked.

**Inside AdviceCard.tsx**

<!--kg-card-begin: markdown-->
```jsx
import React from 'react'
import { CircularButton } from './CircularButton';

interface TextProps {
    id: number,
    adviceText: string,
    handleAdvice(): void,
}

export const AdviceCard = ({ adviceText, id , handleAdvice }: TextProps) => {
    return (
        <div className="relative w-[380px] md:w-[450px] md:h-[280px] bg-[#323a49] mt-20 px-8 pt-8 pb-16 rounded-xl flex flex-col justify-center items-center ">
            <p className="text-md md:text-lg uppercase font-medium text-emerald-400 absolute top-8 mx-auto ">
                Advice
                {" "}
                <span className=" font-bold ml-2 ">
                    #{id}
                </span>
            </p>
            <div className="text-lg md:text-2xl font-manrope font-semibold text-gray-300 leading-8 text-center mt-4">
                "{adviceText}"
            </div>
            <hr className="w-[380px] border-t-1 border-gray-500 mt-8 absolute bottom-16 mx-auto" />
            <div className="absolute -bottom-[30px] mx-auto ">
            <CircularButton handleAdvice={handleAdvice} />
            </div>
        </div>
    )
}

```
<!--kg-card-end: markdown-->

In this component also we are passing three props as you can see.

The three props are:

1. **advice text**
2. **id**
3. **handleAdvice**

Now we have made both the components,  it's time to code the logic for fetching the API and displaying the data that we will get from it.


## Step-3 Fetching the API

So basically, the API returns a single object which contains two fields the **id** and the **adviceText** field.

Now, visit the index.js file inside the Pages folder and create two  constants with the **useState** hook inside the **Home** function, and set their default values as given below.

<!--kg-card-begin: markdown-->
```jsx
const [adviceText ,setAdviceText] =useState<string>("Never regret.
  If it's good, it's wonderful. If it's bad, it's experience.");
 
const [adviceId, setAdviceId] = useState<number>(143);

```
<!--kg-card-end: markdown-->

And also don't forget to import useState from the react library.

Now after that create an arrow function with the name **fetchAdvice** () and inside it fetch the API using the inbuilt fetch() function and store the result inside the constant name **data**.

After that set the two pieces of the state with the value coming from the API  and also create a function name handleAdvice() and call the fetchAdvice() inside it.

<!--kg-card-begin: markdown-->
```jsx
const [adviceText ,setAdviceText] =useState<string>("Never regret.
If it's good, it's wonderful. If it's bad, it's experience.");
  const [adviceId, setAdviceId] = useState<number>(143);

  const fetchAdvice = async () => {

      const res = await fetch(API);
      const data= await res.json();

      setAdviceId(data.slip.id);
      setAdviceText(data.slip.advice);
    };
     
  
  const handleAdvice= () => {
    fetchAdvice();
  };

```
<!--kg-card-end: markdown-->

## Step-4  Import the components  and pass the Props

At last, import the two components from the components folder and add those inside the Home function.

After all that the **index.tsx** will look something like this:

**Inside index.tsx**

<!--kg-card-begin: markdown-->
```jsx
import type { NextPage } from 'next'
import Head from 'next/head'
import { useState } from 'react';
import { AdviceCard } from '../components/AdviceCard'

const API="https://api.adviceslip.com/advice";

const Home: NextPage= () => {

  const [adviceText ,setAdviceText] =useState<string>("Never regret. If it's good, it's wonderful. If it's bad, it's experience.");
  const [adviceId, setAdviceId] = useState<number>(143);

  const fetchAdvice = async () => {

      const res = await fetch(API);
      const data= await res.json();

      setAdviceId(data.slip.id);
      setAdviceText(data.slip.advice);
    };
     
  
  const handleAdvice= () => {
    fetchAdvice();
  };

  return (
    <div className="flex min-h-screen bg-gray-800 flex-col items-center py-2">
      <Head>
        <title>Advice Generator App</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <h1 className="text-emerald-200 font-bold text-2xl md:text-4xl font-manrope mt-4 rounded-xl hover:rounded-xl hover:shadow-lg hover:shadow-emerald-600 hover:bg-emerald-500 hover:text-emerald-100 px-4 py-2 transition duration-300 ease-in ">
        Advice Generator App
        </h1>
      {/* <CircularButton /> */}
      <AdviceCard id={adviceId} adviceText={adviceText} handleAdvice={handleAdvice} />
    </div>
  )
}

export default Home

```
<!--kg-card-end: markdown-->

## Conclusion

Hope you were able to build this **Advice Generator App**.  Feel free to follow me on [Twitter](https://twitter.com/raivikas200) and share this if you like this project 😉.

I hope you like this project and enjoyed building it, I would appreciate ✌️ it if you could share this blog post.

If you think that this was helpful and then please do consider visiting my blog website [nextjsdev.com](https://nextjsdev.com/) and do follow me on **Twitter** and connect with me on **LinkedIn**.

If you were stuck somewhere and not able to find the solution you can check out my completed [Github Repo](https://github.com/raiv200/Advice-Generator-App) here.

Thanks for your time to read this project, if you like this please share it on Twitter and Facebook or any other social media and tag me there.

I will see you in my next blog ✌️. Till then take care and keep building projects.

Some Useful Link:

[Next.js and Tailwind Installation Docs](https://tailwindcss.com/docs/guides/nextjs)

[Github link for the project](https://github.com/raiv200/Advice-Generator-App)

**Connect with me:**

[Twitter Profile](https://twitter.com/raivikas200)

[LinkedIn Profile](https://www.linkedin.com/in/raivikas200/)

[GitHub Profile](https://github.com/raiv200)

[Facebook Profile](https://facebook.com/raivikas200)