Open In App

Quote Generator App using NextJS

Last Updated : 18 Oct, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will build an quote generator using NextJS. The user will be given a button that, when clicked, will retrieve a random quote from the API and display it on the screen. By clicking the button again, users can generate a large number of advices.

Quote-Generator-App-Using-Next-Js

Technologies Used/Prerequisites

Approach / Functionalities:

The provide­d code defines a Re­act component known as App. This component imports nece­ssary dependencie­s, such as useState and useEffe­ct from the ‘react‘ library, as well as style­s from ‘Home.module.css‘. Inside the­ component, the useState­ hook is utilized to manage state variable­s for quote text, author information, and a indicating copied status. Additionally, the­re is a function called gene­rateQuote which fetche­s a random quote asynchronously from an API and updates the state­ accordingly. To ensure this behavior occurs upon initial re­ndering, the useEffe­ct hook triggers the gene­rateQuote function. Lastly, there­ is another function named copyToClipboard that create­s a temporary textarea and facilitate­s copying of the quote to the clipboard while­ managing its copied status.

Steps to create the NextJS Application:

Step 1: Create a new Next.js project using the following command

npx create-next-app QuoteGenerator

Step 2: Change to the project directory:

cd QuoteGenerator

Project Structure:

package.json

{
    "name": "quote-generator",
    "private": true,
    "scripts": {
        "dev": "next dev",
        "build": "next build",
        "start": "next start"
    },
    "dependencies": {
        "next": "^13.4.0",
        "react": "^18.2.0",
        "react-dom": "^18.2.0"
    }
}

Example: In this example, we will see the Quote Generator App using Next.js

Javascript




// index.js
import { useState, useEffect } from 'react';
import styles from '../styles/Home.module.css';
 
const App = () => {
    const [quote, setQuote] = useState('');
    const [author, setAuthor] = useState('');
    const [copied, setCopied] = useState(false);
 
    const generateQuote = async () => {
        try {
            const response = await fetch(
                'https://type.fit/api/quotes');
            const quoteList = await response.json();
            const randomIdx = Math.floor(
                Math.random() * quoteList.length);
            const quoteText = quoteList[randomIdx].text;
            const auth =
                quoteList[randomIdx].author || 'Anonymous';
 
            setQuote(quoteText);
            setAuthor('~ ' + auth);
        } catch (error) {
            console.error('Error fetching quote:', error);
        }
    };
 
    useEffect(() => {
        generateQuote();
    }, []);
 
    const copyToClipboard = () => {
        const textArea = document.createElement('textarea');
        textArea.value = quote;
        document.body.appendChild(textArea);
        textArea.select();
        document.execCommand('copy');
        document.body.removeChild(textArea);
        setCopied(true);
 
        setTimeout(() => setCopied(false), 2000);
    };
 
    return (
        <div className={styles.container}>
            <div className={styles.boxSize}>
                <h1 className={styles.QuoteText}>{quote}</h1>
                <p className={styles.author} id="author">
                    {author}
                </p>
                <hr />
                <div className={styles.QuoteBtn}>
                    <button
                        className={styles.copyButton}
                        onClick={copyToClipboard}
                        disabled={copied}
                    >
                        {copied ? 'Copied!' : 'Copy'}
                    </button>
                    <button
                        className={styles.GenerateQuote_next}
                        onClick={generateQuote}>
                        Next quote
                    </button>
                </div>
            </div>
        </div>
    );
};
 
export default App;


CSS




/* Home.module.css */
 
.boxSize {
    margin: 40px auto;
    padding: 20px;
    border-radius: 10px;
    width: 800px;
    display: flex;
    flex-direction: column;
    align-items: center;
    box-shadow: 0 4px 10px 0px grey;
    background-color: rgba(255, 255, 255, 0.9);
}
 
.QuoteText {
    text-align: center;
    font-size: 28px;
    font-weight: bold;
    margin-bottom: 20px;
    color: #333;
}
 
.author {
    text-align: right;
    font-size: 20px;
    font-style: italic;
    font-family: cursive;
    color: #666;
}
 
.QuoteBtn {
    margin-top: 20px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
}
 
.GenerateQuote_next {
    font-size: 18px;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    padding: 12px 20px;
    font-weight: bold;
    color: white;
    background-color: #2c5e1a;
    transition: background-color 0.3s;
    box-shadow: 0px 0px 10px 0px grey;
}
 
.GenerateQuote_next:hover {
    background-color: #1d3e12;
}
 
.copyButton {
    font-size: 18px;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    padding: 12px 20px;
    font-weight: bold;
    color: white;
    background-color: #007acc;
    transition: background-color 0.3s;
    box-shadow: 0px 0px 10px 0px grey;
}
 
.copyButton:hover {
    background-color: #005aaf;
}
 
.copyButton:disabled {
    background-color: #ccc;
    cursor: not-allowed;
}


Step 3: To run the next.js application use the following command and then go to this URL http://localhost:3000

npm run dev

Output:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads