News App using HTML, CSS and JavaScript With Source Code

thumbnail

Introduction :

The News App is a dynamic and responsive web application that provides users with the latest news articles from various categories. Utilizing HTML, CSS, and JavaScript, along with integration of the News API, the project enables users to explore news related to finance, sports, crypto, international affairs, technical topics, AI, and education. The interface is designed to be intuitive, offering a navigation bar for selecting news categories, a search bar for customized queries, and a visually appealing card-based layout to present news articles. In the ever-evolving landscape of web development, the News App stands as a testament to the fusion of creativity and technological innovation. Crafted with HTML, CSS, and JavaScript, this project presents a dynamic platform that brings the latest news articles from around the world to users’ fingertips. The seamless integration of the News API amplifies the application’s capabilities, offering a diverse array of news categories, including finance, sports, crypto, international affairs, technical developments, AI, and education. Through its modular design, purposeful functions, and seamless integration of APIs, this project represents a harmonious blend of design aesthetics and technological prowess, catering to the ever-growing demand for dynamic and user-centric web applications

Explanation :

HTML Structure:

Navigation Bar (<nav>):

  • Divided into two main sections: nav-links for category selection and search-bar for custom queries.
  • Category links are interactive and trigger a function (onNavItemClick) when clicked.
  • Search bar includes an input field (search-text) and a button (search-button).

Main Content (<main>):

  • Contains a container (cards-container) for dynamically displaying news cards.

Template for News Cards (<template>):

  • A hidden template for news cards with placeholders for news image, title, source, and description.

JavaScript Logic:

The JavaScript logic orchestrates the dynamic functionality of the News App, creating a seamless user experience. Constants like API_KEY and url authenticate and facilitate communication with the News API. Event listeners capture user actions, triggering functions like fetchNews to asynchronously retrieve articles, and onNavItemClick to dynamically update the displayed news based on user-selected categories. The modular design allows for efficient rendering of news cards through functions like bindData and fillDataInCard, ensuring a smooth and interactive presentation of news content.

Functions explanation:

  1. fetchNews(query):

    • Purpose: Initiates asynchronous fetching of news articles from the News API based on the provided query.
    • Usage: Automatically triggered on page load and category selection.
  2. bindData(articles):

    • Purpose: Dynamically populates the news cards container with articles, maintaining an organized and updated display.
    • Usage: Called after fetching news, ensuring the user is presented with the latest information.
  3. fillDataInCard(cardClone, article):

    • Purpose: Fills data into each news card clone, ensuring a consistent and visually appealing presentation.
    • Usage: Called iteratively for each article to construct individual news cards.
  4. onNavItemClick(id):

    • Purpose: Manages category selection, dynamically updating the displayed news, and highlighting the active category.
    • Usage: Triggered when a user clicks on a specific news category, providing a personalized news experience.
  5. Search Functionality:

    • Purpose: Empowers users to input custom queries, enhancing the application’s versatility and catering to individual interests.
    • Usage: Activated upon the click event of the search button, delivering tailored news content.

Source Code :

HTML (index.html)

				
					



    
    
    
    <title>News App</title>
    




    <nav>
        <div class="main-nav container flex">

            <div class="nav-links">
                <ul class="flex">
                    <li class="hover-link nav-item" id="finance">Finance</li>
                    <li class="hover-link nav-item" id="sports">Sports</li>
                    <li class="hover-link nav-item" id="crypto">Crypto</li>
                    <li class="hover-link nav-item" id="international">
                        International</li>
                    <li class="hover-link nav-item" id="technical">Technical</li>
                    <li class="hover-link nav-item" id="AI">AI</li>
                    <li class="hover-link nav-item" id="education">Education</li>
                </ul>
            </div>
            <div class="search-bar flex">
                
                <button id="search-button" class="search-button">Search</button>
            </div>
        </div>
    </nav>


    <main>
        <div class="cards-container container flex" id="cards-container">

        </div>
    </main>

    
        <div class="card">
            <div class="card-header">
                <img data-lazyloaded="1" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0MDAiIGhlaWdodD0iMjAwIiB2aWV3Qm94PSIwIDAgNDAwIDIwMCI+PHJlY3Qgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgc3R5bGU9ImZpbGw6I2NmZDRkYjtmaWxsLW9wYWNpdHk6IDAuMTsiLz48L3N2Zz4=" width="400" height="200" decoding="async" data-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>
    

    


 
				
			

CSS (style.css)

				
					@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@500&amp;family=Roboto:wght@500&amp;display=swap");

* {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}



body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background-color: #c3c3c3;
}

p {
    font-family: "Roboto", sans-serif;
    opacity: .8;
    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: #484e52;
    color: white;
    position: fixed;
    top: 0;
    z-index: 99;
    left: 0;
    right: 0;
}

.main-nav {
    justify-content: space-between;
    padding-block: 8px;
}



.nav-links ul {
    gap: 16px;
}

.hover-link {
    cursor: pointer;
}


.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: #208c5b;
    color: white;
    padding: 8px 24px;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-family: "Roboto", sans-serif;
}



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;

}

.hover-link:hover {
    color: #b9b9b9;
    text-decoration: underline;
}
				
			

JavaScript (script.js)

				
					const API_KEY = "1d3a0eefa97b499d8fbc4ee93eeb40b7";
const url = "https://newsapi.org/v2/everything?q=";

window.addEventListener("load", () =&gt; fetchNews("India"));

function reload() {
    window.location.reload();
}

async function fetchNews(query) {
    const res = await fetch(`${url}${query}&amp;apiKey=${API_KEY}`);
    const data = await res.json();
    bindData(data.articles);
    console.log(data)
}

function bindData(articles) {
    const cardsContainer = document.getElementById("cards-container");
    const newsCardTemplate = document.getElementById("template-news-card");

    cardsContainer.innerHTML = "";

    articles.forEach((article) =&gt; {
        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", () =&gt; {
        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", () =&gt; {
    const query = searchText.value;
    if (!query) return;
    fetchNews(query);
    curSelectedNav?.classList.remove("active");
    curSelectedNav = null;
});
				
			

Output :

output

Find More Projects

Build a Quiz Game Using HTML CSS and JavaScript Introduction Hello coders, you might have played various games, but were you aware …

Emoji Catcher Game Using HTML CSS and JavaScript Introduction Hello Coders, Welcome to another new blog. In this article we’ve made a …

Typing Challenge Using HTML CSS and JavaScript Introduction Hello friends, all you developer friends are welcome to our new project. If you …

Breakout Game Using HTML CSS and JavaScript With Source Code Introduction Hello friends, welcome to today’s new blog post. All of you …

Digital and Analog Clock using HTML CSS and JavaScript Introduction : This project is a digital clock and stopwatch system, which allows …

Coffee Shop Website using HTML, CSS & JavaScript Introduction : This project is a website for coffee house business. It uses HTML …

More HTML CSS JS Projects
Get Huge Discounts

All Coding Handwritten Notes