Step-by-Step Implementation of Our Dictionary App
Step-by-Step Implementation of Our Dictionary App
In this module, we’ll build the Dictionary App from scratch. We’ll create the Vite project, set up the directory structure, render our main component, add the search logic, connect it with APIs for definitions and suggestions, and style it for a clean user interface.
1) Set up the environment
We’ll use Vite to quickly scaffold a React app.
Open your terminal and run:
npm create vite@latest dictionary-app
Choose the following options:
- Project name: dictionary-app
- Framework: React
- Variant: JavaScript
Next, install dependencies:
cd dictionary-app
npm install
Start the development server:
npm run dev
You’ll get a local URL like http://localhost:5173/. Opening it in the browser will show the Vite + React starter page.
2) Create Application Structure (Directory Structure)
After setting up, you’ll see this structure:
dictionary-app/
├── index.html
├── package.json
├── vite.config.js
├── public/
└── src/
├── App.jsx
├── App.css
├── index.css
└── main.jsx
- index.html: Contains <div id="root"></div>, the container where React mounts the app.
- src/main.jsx: Entry point that renders the <App /> component.
- src/App.jsx: The main component that holds our dictionary logic.
- src/App.css and src/index.css: Styling files for layout and components.
3) Rendering App in main.jsx
Open src/main.jsx. By default, it looks like this:
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.jsx'
createRoot(document.getElementById('root')).render(
<StrictMode>
<App />
</StrictMode>,
)
This code finds the root element in index.html and mounts the <App /> component there.
4) Building the Dictionary Logic in App.jsx
Now open src/App.jsx and replace it with our dictionary app code.
Step 1: Import React hooks and CSS
import { useState, useEffect } from "react";
import "./App.css";
We use useState to store word input, results, errors, and suggestions. useEffect will help us fetch suggestions dynamically.
Step 2: Define state
const [word, setWord] = useState("");
const [results, setResults] = useState(null);
const [error, setError] = useState(null);
const [suggestions, setSuggestions] = useState([]);
- word: user input
- results: fetched dictionary results
- error: error messages if the word is invalid or API fails
- suggestions: possible word suggestions
Step 3: Fetch word suggestions
We use the Datamuse API for suggestions and then check if those suggestions exist in the Dictionary API.
useEffect(() => {
if (word.length > 1) {
fetch(`https://api.datamuse.com/sug?s=${word}`)
.then((res) => res.json())
.then(async (data) => {
const checks = await Promise.all(
data.map((item) => validateSuggestion(item.word))
);
const validSuggestions = [...new Set(checks.filter(Boolean))];
setSuggestions(validSuggestions);
})
.catch(() => setSuggestions([]));
} else {
setSuggestions([]);
}
}, [word]);
Step 4: Fetch definitions on submit
const handleSubmit = async (e) => {
e.preventDefault();
if (!word) return;
try {
setError(null);
setResults(null);
const res = await fetch(
`https://api.dictionaryapi.dev/api/v2/entries/en/${word}`
);
if (!res.ok) {
setError("Word not found.");
return;
}
const data = await res.json();
const entry = data[0];
const definitions = entry.meanings.flatMap((m) =>
m.definitions.map((d) => ({
partOfSpeech: m.partOfSpeech,
definition: d.definition,
example: d.example,
synonyms: d.synonyms,
}))
);
setResults({
word: entry.word,
phonetic: entry.phonetic,
definitions,
});
} catch {
setError("Something went wrong. Try again.");
}
};
This fetches data from the dictionary API, extracts phonetics, definitions, examples, and synonyms, then stores it in results.
Step 5: Return the UI
return (
<div className="app">
<h1>My Dictionary</h1>
<form onSubmit={handleSubmit} className="search-form">
<input
type="text"
placeholder="Enter a word..."
value={word}
onChange={(e) => setWord(e.target.value)}
/>
<button type="submit">Search</button>
</form>
{suggestions.length > 0 && (
<div className="suggestions">
<p>Did you mean:</p>
{suggestions.slice(0, 5).map((sug, i) => (
<button key={i} onClick={() => setWord(sug)}>
{sug}
</button>
))}
</div>
)}
{error && <div className="error">{error}</div>}
{results && (
<div className="results">
<h2>
{results.word}{" "}
{results.phonetic && <span className="phonetic">({results.phonetic})</span>}
</h2>
<ul>
{results.definitions.map((def, index) => (
<li key={index}>
<strong>{def.partOfSpeech}:</strong> {def.definition}
{def.example && <p className="example">{def.example}</p>}
{def.synonyms && def.synonyms.length > 0 && (
<p className="synonyms">
Synonyms: {def.synonyms.slice(0, 5).join(", ")}
</p>
)}
</li>
))}
</ul>
</div>
)}
<footer>
Made by Jaishree Tomar for{" "}
<a href="https://www.guvi.in" target="_blank" rel="noreferrer">
GUVI
</a>
</footer>
</div>
);
This UI covers search input, suggestions, results, errors, and footer.
5) Styling with CSS
We use App.css for styling. Key highlights:
- Dark gradient background with a centered container.
- Inputs styled with rounded corners and glowing focus.
- Suggestion buttons outlined in cyan, turning solid on hover.
- Results displayed clearly with highlighted synonyms and examples.
Our code:
body {
margin: 0;
font-family: "Poppins", sans-serif;
background: linear-gradient(135deg, #0f0f0f, #1a1a1a, #000000);
color: #f1f1f1;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
.app {
text-align: center;
padding: 2rem;
border-radius: 1.5rem;
background: rgba(30, 30, 30, 0.9);
box-shadow: 0 0 30px rgba(0, 255, 255, 0.2);
width: 90%;
max-width: 700px;
animation: fadeIn 0.8s ease-in-out;
}
h1 {
font-size: 2.2rem;
margin-bottom: 1.5rem;
color: #00ffff;
text-shadow: 0 0 10px #00ffffaa;
}
.search-form {
margin-bottom: 1rem;
}
.search-form input {
padding: 0.7rem;
font-size: 1rem;
width: 250px;
border-radius: 10px;
border: none;
outline: none;
margin-right: 0.5rem;
}
.search-form button {
padding: 0.7rem 1rem;
font-size: 1rem;
background: #00ffff;
color: black;
border: none;
border-radius: 10px;
cursor: pointer;
transition: 0.2s;
}
.search-form button:hover {
background: #00cccc;
}
.suggestions {
margin-top: 0.5rem;
}
.suggestions p {
font-size: 0.9rem;
color: #aaa;
}
.suggestions button {
margin: 0.25rem;
padding: 0.4rem 0.8rem;
background: #111;
border: 1px solid #00ffff;
border-radius: 8px;
cursor: pointer;
color: #00ffff;
transition: 0.2s;
}
.suggestions button:hover {
background: #00ffff;
color: black;
}
.error {
margin-top: 1.5rem;
color: #ff4d4d;
}
.results {
margin-top: 2rem;
text-align: left;
}
.results h2 {
color: #ffcc00;
}
.phonetic {
font-size: 1rem;
color: #aaa;
}
.example {
font-style: italic;
color: #bbb;
}
.synonyms {
color: #7fffd4;
}
footer {
margin-top: 2rem;
font-size: 0.9rem;
color: #888;
}
footer a {
color: #00ffff;
text-decoration: none;
}
footer a:hover {
text-decoration: underline;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(15px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
6) Final Touches and Deployment
- Add a footer credit with your name and GUVI link.
- Test by searching words like “beautiful” or “run”. You’ll see definitions, examples, and synonyms.
- Try partial words like “bea” to check suggestions.
To deploy:
npm run build
This generates a dist/ folder. You can host it easily on Netlify or Vercel by uploading the dist/ directory.
Now your Dictionary App is complete. It takes input, shows real-time suggestions, fetches dictionary data, and displays it in a clean interface.











