Random Quote Generator & Narrator

Inspirational quote engine featuring category filters, copy to clipboard, Twitter/X share intent, and Web Speech API audio narration.

Difficulty: Beginner Est. Time: 15 mins Vanilla JS (ES6+) Includes HTML, CSS, JS & README (.ZIP)
Live UI Runner

Random Quote Generator & Narrator

live-sandbox://quote-generator

1. Project Overview & Features

The Random Quote Generator & Narrator is an essential frontend project designed to help you bridge the gap between learning JavaScript syntax and building interactive, responsive web applications.

Key Features Implemented:

  • Library of curated quotes by famous pioneers
  • Filter by category (Inspiration, Technology, Philosophy)
  • Audio speech read-aloud using the browser Web Speech API
  • Instant copy quote and share to Twitter/X

2. Step-by-Step Code Walkthrough

A Step 1: Semantic HTML Structure

We structure the interface using clean, semantic HTML elements. This ensures maximum accessibility and provides intuitive hooks for CSS classes and JavaScript query selectors.

HTML (index.html)
<div class="quote-card">
  <div class="category-tabs">
    <button class="cat-btn active" data-cat="all">All</button>
    <button class="cat-btn" data-cat="tech">Tech</button>
    <button class="cat-btn" data-cat="wisdom">Wisdom</button>
    <button class="cat-btn" data-cat="motivation">Motivation</button>
  </div>

  <div class="quote-body">
    <i class="fas fa-quote-left quote-icon"></i>
    <p id="quote-text" class="quote-text">The only way to do great work is to love what you do.</p>
    <div class="author-row">
      <span class="author-line"></span>
      <span id="quote-author" class="quote-author">Steve Jobs</span>
    </div>
  </div>

  <div class="action-footer">
    <div class="tool-actions">
      <button id="speak-btn" class="action-btn" title="Listen (Text to Speech)"><i class="fas fa-volume-up"></i></button>
      <button id="copy-btn" class="action-btn" title="Copy to Clipboard"><i class="far fa-copy"></i></button>
      <button id="tweet-btn" class="action-btn" title="Share on Twitter"><i class="fab fa-twitter"></i></button>
    </div>
    <button id="new-quote-btn" class="btn-new-quote"><i class="fas fa-sync-alt"></i> New Quote</button>
  </div>
</div>

B Step 2: Styling & Responsive CSS

Modern CSS flexbox and grid layouts are used to make the UI look polished, centered, and responsive across desktop, tablet, and mobile screens.

CSS (style.css)
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
body {
  background: linear-gradient(135deg, #083344 0%, #0f172a 100%);
  color: #f8fafc;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.quote-card {
  background: #1e293b;
  border: 1px solid #334155;
  border-radius: 24px;
  padding: 32px;
  width: 100%;
  max-width: 520px;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4);
}
.category-tabs {
  display: flex;
  gap: 8px;
  margin-bottom: 24px;
  overflow-x: auto;
}
.cat-btn {
  background: #0f172a;
  border: 1px solid #334155;
  color: #94a3b8;
  padding: 6px 14px;
  border-radius: 20px;
  font-size: 0.8rem;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.2s;
}
.cat-btn.active {
  background: #06b6d4;
  color: #0f172a;
  border-color: #06b6d4;
}
.quote-body {
  margin-bottom: 28px;
  min-height: 120px;
}
.quote-icon {
  font-size: 2rem;
  color: #06b6d4;
  margin-bottom: 12px;
  opacity: 0.8;
}
.quote-text {
  font-size: 1.35rem;
  font-weight: 600;
  line-height: 1.5;
  color: #f8fafc;
  margin-bottom: 16px;
}
.author-row {
  display: flex;
  align-items: center;
  gap: 12px;
}
.author-line {
  width: 32px;
  height: 2px;
  background: #06b6d4;
}
.quote-author {
  color: #94a3b8;
  font-size: 1rem;
  font-weight: 500;
  font-style: italic;
}
.action-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-top: 1px solid #334155;
  padding-top: 20px;
}
.tool-actions {
  display: flex;
  gap: 8px;
}
.action-btn {
  width: 42px;
  height: 42px;
  border-radius: 12px;
  background: #0f172a;
  border: 1px solid #334155;
  color: #cbd5e1;
  font-size: 1rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
}
.action-btn:hover {
  border-color: #06b6d4;
  color: #06b6d4;
}
.btn-new-quote {
  background: #06b6d4;
  color: #0f172a;
  border: none;
  padding: 12px 20px;
  border-radius: 12px;
  font-weight: 700;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: opacity 0.2s;
}
.btn-new-quote:hover {
  opacity: 0.9;
}

C Step 3: JavaScript Logic & Event Handling

Here is the complete JavaScript code handling the state, event listeners, mathematical logic, and dynamic DOM rendering:

JavaScript (script.js)
const quotes = [
  { text: 'The only way to do great work is to love what you do.', author: 'Steve Jobs', category: 'motivation' },
  { text: 'Talk is cheap. Show me the code.', author: 'Linus Torvalds', category: 'tech' },
  { text: 'Programs must be written for people to read, and only incidentally for machines to execute.', author: 'Harold Abelson', category: 'tech' },
  { text: 'Knowing yourself is the beginning of all wisdom.', author: 'Aristotle', category: 'wisdom' },
  { text: 'Simplicity is prerequisite for reliability.', author: 'Edsger W. Dijkstra', category: 'tech' },
  { text: 'It does not matter how slowly you go as long as you do not stop.', author: 'Confucius', category: 'motivation' },
  { text: 'Turn your wounds into wisdom.', author: 'Oprah Winfrey', category: 'wisdom' },
  { text: 'First, solve the problem. Then, write the code.', author: 'John Johnson', category: 'tech' }
];

let currentCat = 'all';
let currentQuote = quotes[0];

const quoteText = document.getElementById('quote-text');
const quoteAuthor = document.getElementById('quote-author');
const newQuoteBtn = document.getElementById('new-quote-btn');
const speakBtn = document.getElementById('speak-btn');
const copyBtn = document.getElementById('copy-btn');
const tweetBtn = document.getElementById('tweet-btn');
const catBtns = document.querySelectorAll('.cat-btn');

function getRandomQuote() {
  const filtered = currentCat === 'all' ? quotes : quotes.filter(q => q.category === currentCat);
  const available = filtered.filter(q => q.text !== currentQuote.text);
  const pool = available.length > 0 ? available : filtered;
  const pick = pool[Math.floor(Math.random() * pool.length)];
  currentQuote = pick;

  quoteText.textContent = pick.text;
  quoteAuthor.textContent = pick.author;
}

catBtns.forEach(btn => {
  btn.addEventListener('click', () => {
    catBtns.forEach(b => b.classList.remove('active'));
    btn.classList.add('active');
    currentCat = btn.dataset.cat;
    getRandomQuote();
  });
});

newQuoteBtn.addEventListener('click', getRandomQuote);

// Web Speech API Narrator
speakBtn.addEventListener('click', () => {
  if ('speechSynthesis' in window) {
    const utterance = new SpeechSynthesisUtterance(`${currentQuote.text} by ${currentQuote.author}`);
    utterance.rate = 0.95;
    window.speechSynthesis.speak(utterance);
  } else {
    alert('Text-to-speech is not supported in this browser.');
  }
});

// Copy Quote
copyBtn.addEventListener('click', () => {
  const text = `"${currentQuote.text}" β€” ${currentQuote.author}`;
  navigator.clipboard.writeText(text).then(() => {
    copyBtn.innerHTML = '<i class="fas fa-check" style="color:#10b981"></i>';
    setTimeout(() => {
      copyBtn.innerHTML = '<i class="far fa-copy"></i>';
    }, 1500);
  });
});

// Share on Twitter/X
tweetBtn.addEventListener('click', () => {
  const tweetUrl = `https://twitter.com/intent/tweet?text=${encodeURIComponent(`"${currentQuote.text}" β€” ${currentQuote.author}`)}`;
  window.open(tweetUrl, '_blank');
});

3. Core JavaScript Concepts You Learned

Array Indexing

Crucial concept utilized to power the dynamic state, user interactions, and styling of this project.

Web Speech API (Synthesis)

Crucial concept utilized to power the dynamic state, user interactions, and styling of this project.

Clipboard API

Crucial concept utilized to power the dynamic state, user interactions, and styling of this project.

Social Sharing Links

Crucial concept utilized to power the dynamic state, user interactions, and styling of this project.

DOM Text Updates

Crucial concept utilized to power the dynamic state, user interactions, and styling of this project.

4. How to Run Locally on Your Computer

  1. Download the project ZIP: Click the Download Project (.ZIP) button at the top or in the live runner to save quote-generator-project.zip.
  2. Extract the archive: Unzip the downloaded file. Inside you will find separate index.html, style.css, script.js, index-standalone.html, and a comprehensive README.md.
  3. Open in any browser: Simply double-click index.html (or index-standalone.html) to open and test immediately in Chrome, Firefox, Safari, or Edge.
  4. Edit in Visual Studio Code: Open the extracted folder in VS Code. Right-click index.html and select "Open with Live Server" to enjoy instant live reloading as you modify HTML, CSS, or JS!

Bonus Challenges for Learners

Ready to level up? Try adding these extra features on your own:

  • Add sound effects or audio feedback for user button clicks.
  • Add custom theme color customizer with CSS variables.
  • Export the results to PDF or copy as a formatted text summary.

Other Beginner Projects You Might Like

Beginner15 mins
UI & DOM

Color Flipper & Gradient Generator

Generate dynamic random hex and RGB colors, linear gradient backgrounds with angle sliders, color palettes, and copy codes with one click.

Math.random() & Hex formattingDOM Style ManipulationClipboard API (writeText)+2