Introduction
Hello, developers! I’m excited to introduce my latest project: Abhi ki News. This project is a dynamic news website component designed to fetch and display news articles in a clean and user-friendly interface. It's a fantastic way to enhance your frontend development skills using HTML, CSS, and JavaScript, and provides a practical example of integrating an external API into your web application.
Project Overview
Abhi ki News is a web application that fetches and displays news articles based on user input or predefined categories. The component features a modern design with a responsive layout, making it suitable for both desktop and mobile devices. This project demonstrates how to create a functional news interface that fetches live data from an API and presents it in an engaging format.
Features
- Dynamic News Fetching: Retrieves and displays news articles from an external API based on user queries or predefined categories.
- Responsive Design: Ensures the news interface is visually appealing on all devices.
- Hover Effects: Adds interactivity to the news cards with subtle hover effects.
- Search Functionality: Allows users to search for news articles by keyword.
Technologies Used
- HTML: Provides the structure for the news interface.
- CSS: Styles the component to create a visually appealing and responsive design.
- JavaScript: Handles data fetching, user interactions, and dynamically updates the content.
Project Structure
Here’s an overview of the project structure:
Abhi-ki-News/
├── index.html
├── style.css
└── script.js
- index.html: Contains the HTML structure for the news component.
- style.css: Includes CSS styles to create an engaging and responsive design.
- script.js: Handles the logic for fetching and displaying news articles.
Installation
To get started with the project, follow these steps:
-
Clone the repository:
git clone https://github.com/abhishekgurjar-in/Abhi-ki-News.git
-
Open the project directory:
cd Abhi-ki-News
-
Run the project:
- Open the
index.html
file in a web browser to view the news interface.
- Open the
Usage
- Open the application in a web browser.
- Click on a category (e.g., IPL, Finance, Politics) to fetch news articles related to that category.
- Use the search bar to find news articles by entering relevant keywords.
- Interact with the news cards by hovering over them to see the hover effects.
Code Explanation
HTML
The index.html
file defines the structure of the news interface. Here’s a snippet:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Abhi ki News</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<nav>
<div class="main-nav container flex">
<a href="#" onclick="reload()" class="company-logo">
<img src="./assets/logo.png" alt="company logo">
</a>
<div class="nav-links">
<ul class="flex">
<li class="hover-link nav-item" id="ipl" onclick="onNavItemClick('ipl')">IPL</li>
<li class="hover-link nav-item" id="finance" onclick="onNavItemClick('finance')">Finance</li>
<li class="hover-link nav-item" id="politics" onclick="onNavItemClick('politics')">Politics</li>
</ul>
</div>
<div class="search-bar flex">
<input id="search-text" type="text" class="news-input" placeholder="e.g. Science">
<button id="search-button" class="search-button">Search</button>
</div>
</div>
</nav>
<main>
<div id="loader" class="loader">Loading...</div>
<div id="error-message" class="error-message"></div>
<div class="cards-container container flex" id="cards-container">
</div>
</main>
<template id="template-news-card">
<div class="card">
<div class="card-header">
<img src="https://via.placeholder.com/400x200" alt="news-image" id="news-img">
</div>
<div class="card-content">
<h3 id="news-title">This is the Title</h3>
<h6 class="news-source" id="news-source">End Gadget 26/08/2023</h6>
<p class="news-desc" id="news-desc">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Recusandae saepe quis voluptatum quisquam vitae doloremque facilis molestias quae ratione cumque!</p>
</div>
</div>
</template>
<script src="script.js"></script>
</body>
</html>
CSS
The style.css
file styles the news interface to ensure it’s visually appealing and responsive. Below are some key styles:
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@500&family=Roboto:wght@500&display=swap");
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
:root {
--primary-text-color: #183b56;
--secondary-text-color: #577592;
--accent-color: #2294ed;
--accent-color-dark: #1d69a3;
}
body {
font-family: "Poppins", sans-serif;
color: var(--primary-text-color);
}
p {
font-family: "Roboto", sans-serif;
color: var(--secondary-text-color);
line-height: 1.4rem;
}
a {
text-decoration: none;
}
ul {
list-style: none;
}
.flex {
display: flex;
align-items: center;
}
.container {
max-width: 1180px;
margin-inline: auto;
overflow: hidden;
}
nav {
background-color: #f3faff;
box-shadow: 0 0 4px #bbd0e2;
position: fixed;
top: 0;
z-index: 99;
left: 0;
right: 0;
}
.main-nav {
justify-content: space-between;
padding-block: 8px;
}
.company-logo img {
width: 120px;
height: 120px;
}
.nav-links ul {
gap: 16px;
}
.hover-link {
cursor: pointer;
}
.hover-link:hover {
color: var(--secondary-text-color);
}
.hover-link:active {
color: red;
}
.nav-item.active {
color: var(--accent-color);
}
.search-bar {
height: 32px;
gap: 8px;
}
.news-input {
width: 200px;
height: 100%;
padding-inline: 12px;
border-radius: 4px;
border: 2px solid #bbd0e2;
font-family: "Roboto", sans-serif;
}
.search-button {
background-color: var(--accent-color);
color: white;
padding: 8px 24px;
border: none;
border-radius: 4px;
cursor: pointer;
font-family: "Roboto", sans-serif;
}
.search-button:hover {
background-color: var(--accent-color-dark);
}
main {
padding-block: 20px;
margin-top: 80px;
}
.cards-container {
justify-content: space-between;
flex-wrap: wrap;
row-gap: 20px;
align-items: start;
}
.card {
width: 360px;
min-height: 400px;
box-shadow: 0 0 4px #d4ecff;
border-radius: 4px;
cursor: pointer;
background-color: #fff;
overflow: hidden;
transition: all 0.3s ease;
}
.card:hover {
box-shadow: 1px 1px 8px #d4ecff;
background-color: #f9fdff;
transform: translateY(-2px);
}
.card-header img {
width: 100%;
height: 180px;
object-fit: cover;
}
.card-content {
padding: 12px;
}
.news-source {
margin-block: 12px;
}
/* Loader styles */
.loader {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 1.5rem;
color: var(--primary-text-color);
}
/* Error message styles */
.error-message {
color: red;
font-size: 1.2rem;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
JavaScript
The script.js
file handles data fetching and dynamically updates the news cards. Here’s the code:
const API_KEY = "1d3a0eefa97b499d8fbc4ee93eeb40b7";
const url = "https://newsapi.org/v2/everything?q=";
window.addEventListener("load", () => fetchNews("India"));
function reload() {
window.location.reload();
}
async function fetchNews(query) {
// Show loader before making the API request
showLoader(true);
try {
const res = await fetch(`${url}${query}&apiKey=${API_KEY}`);
if (!res.ok) throw new Error("Network response was not ok");
const data = await res.json();
if (data.articles.length === 0) {
showError("No news articles found.");
} else {
bindData(data.articles);
}
} catch (error) {
showError("Failed to fetch news. Please try again later.");
} finally {
// Hide loader after the API request completes
showLoader(false);
}
}
function bindData(articles) {
const cardsContainer = document.getElementById("cards-container");
const newsCardTemplate = document.getElementById("template-news-card");
cardsContainer.innerHTML = "";
articles.forEach((article) => {
if (!article.urlToImage) return;
const cardClone = newsCardTemplate.content.cloneNode(true);
fillDataInCard(cardClone, article);
cardsContainer.appendChild(cardClone);
});
}
function fillDataInCard(cardClone, article) {
const newsImg = cardClone.querySelector("#news-img");
const newsTitle = cardClone.querySelector("#news-title");
const newsSource = cardClone.querySelector("#news-source");
const newsDesc = cardClone.querySelector("#news-desc");
newsImg.src = article.urlToImage;
newsTitle.innerHTML = article.title;
newsDesc.innerHTML = article.description;
const date = new Date(article.publishedAt).toLocaleString("en-US", {
timeZone: "Asia/Jakarta",
});
newsSource.innerHTML = `${article.source.name} · ${date}`;
cardClone.firstElementChild.addEventListener("click", () => {
window.open(article.url, "_blank");
});
}
let curSelectedNav = null;
function onNavItemClick(id) {
fetchNews(id);
const navItem = document.getElementById(id);
curSelectedNav?.classList.remove("active");
curSelectedNav = navItem;
curSelectedNav.classList.add("active");
}
const searchButton = document.getElementById("search-button");
const searchText = document.getElementById("search-text");
searchButton.addEventListener("click", () => {
const query = searchText.value;
if (!query) return;
fetchNews(query);
curSelectedNav?.classList.remove("active");
curSelectedNav = null;
});
function showLoader(isVisible) {
const loader = document.getElementById("loader");
if (isVisible) {
loader.style.display = "block";
} else {
loader.style.display = "none";
}
}
function showError(message) {
const cardsContainer = document.getElementById("cards-container");
cardsContainer.innerHTML = `<div class="error-message">${message}</div>`;
}
Live Demo
You can explore the live demo of the project here.
Conclusion
Abhi ki News is a practical example of integrating external APIs into a web application and creating a responsive, user-friendly news interface. I hope this project helps you learn more about API integration and frontend development. Feel free to modify and expand upon this project to suit your needs!
Credits
- API Source: News API
- Design Inspiration: Various news websites
Top comments (0)