Open In App

Quote Generator App using NextJS

Last Updated : 02 Aug, 2024
Comments
Improve
Suggest changes
Like Article
Like
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

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;
}
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;

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:


Next Article

Similar Reads