Skip to Content
✨ v2.2.4 Released - See the release notes
DocumentationMCA-420 (B) : Lab on Web Programming8. Node.js News Website

Q8. Demonstrate the Use of Node.js in a Website

Question 8:
Design a website using Node.js, Express, and server-side JavaScript.

In this assignment, we will create a dynamic news website that demonstrates:

  • Node.js Basics – Event-driven server-side JavaScript
  • Express Framework – Request/Response handling, routes, controllers
  • MVC Pattern – Organized structure with controllers and routes
  • External API Integration – Fetch news from NewsAPI.org 
  • Fallback Mechanism – If API fails, load data from local JSON files
  • EJS Templates – Render news dynamically with Bootstrap 5 UI

Example: Node.js News Website

File Structure:

mca-assignments-8/ ├── app.js ├── routes/ │ └── newsRoutes.js ├── controllers/ │ └── newsController.js ├── views/ │ ├── index.ejs │ ├── about.ejs │ └── layout.ejs ├── public/ │ ├── img/profile.webp │ └── css/style.css └── data/ ├── topheadlines.json ├── business.json ├── technology.json ├── sports.json └── health.json

Code Implementation

File Name: app.js

const express = require("express"); const app = express(); const path = require("path"); const newsRoutes = require("./routes/newsRoutes"); const expressLayouts = require("express-ejs-layouts"); app.set("view engine", "ejs"); app.set("views", path.join(__dirname, "views")); app.use(express.static(path.join(__dirname, "public"))); // Layouts enable app.use(expressLayouts); app.set("layout", "layout"); // Routes app.use("/", newsRoutes); const PORT = process.env.PORT || 5000; app.listen(PORT, () => { console.log(`Ansari : Server run at \n🌐 http://localhost:${PORT}`); });

File Name: routes/newsRoutes.js

// routes\newsRoutes.js const express = require("express"); const router = express.Router(); const newsController = require("../controllers/newsController"); // Homepage (Top Headlines) router.get("/", newsController.getTopHeadlines); // Category Route router.get("/category/:cat", newsController.getCategoryNews); // About Me Page router.get("/about", (req, res) => { res.render("about"); }); module.exports = router;

File Name: controllers/newsController.js

// controllers/newsController.js const axios = require("axios"); const fs = require("fs"); const path = require("path"); const API_KEY = "c3ddfd9e52fc4d83aea9e39dc25cf758"; async function fetchNews(category, res) { const url = `https://newsapi.org/v2/top-headlines?country=us&category=${category}&apiKey=${API_KEY}`; try { const response = await axios.get(url); let articles = response.data.articles; if (articles && articles.length > 0) { return res.render("index", { articles, category }); } console.log(`No articles from API for ${category}, loading local JSON...`); const fallbackPath = path.join(__dirname, `../data/${category}.json`); const fallbackData = JSON.parse(fs.readFileSync(fallbackPath, "utf-8")); return res.render("index", { articles: fallbackData.articles, category }); } catch (error) { console.error("API Error:", error.message); try { const fallbackPath = path.join(__dirname, `../data/${category}.json`); const fallbackData = JSON.parse(fs.readFileSync(fallbackPath, "utf-8")); return res.render("index", { articles: fallbackData.articles, category }); } catch (fsErr) { console.error("back JSON Error:", fsErr.message); return res.render("index", { articles: [], category }); } } } exports.getTopHeadlines = (req, res) => fetchNews("general", res); exports.getCategoryNews = (req, res) => { const category = req.params.cat; fetchNews(category, res); };

File Name: views/index.ejs

<h2 class="mb-4 text-capitalize text-center fw-bold"><%= category %> News</h2> <div class="row"> <% if (articles && articles.length > 0) { %> <% articles.forEach(article => { %> <div class="col-md-4 mb-4"> <div class="card h-100 shadow-lg border-0 rounded-4 overflow-hidden hover-card"> <img src="<%= article.urlToImage %>" class="card-img-top img-fluid" alt="news" onerror="this.onerror=null;this.src='/img/placeholder.png';" > <div class="card-body d-flex flex-column"> <h5 class="card-title fw-semibold text-truncate-2"><%= article.title %></h5> <p class="card-text text-muted"><%= article.description || "No description available." %></p> <div class="mt-auto"> <a href="<%= article.url %>" target="_blank" class="btn btn-gradient w-100">Read More</a> </div> </div> <div class="card-footer bg-light text-muted small"> <i class="bi bi-newspaper"></i> <%= article.source.name %> | <%= new Date(article.publishedAt).toLocaleString() %> </div> </div> </div> <% }); %> <% } else { %> <div class="text-center py-5"> <img src="/img/placeholder.png" class="mb-3" style="max-width:150px;"> <h5 class="text-muted">No news available at the moment</h5> </div> <% } %> </div>

File Name: views/about.ejs

<!-- About Section --> <section class="container py-5" style="min-height: 85vh;"> <div class="row justify-content-center"> <div class="col-md-8"> <div class="card shadow-lg border-0 rounded-3"> <div class="card-body text-center p-5"> <img src="/img/profile.webp" alt="Ansari Intesab" class="rounded-circle mb-3" width="150" height="150"> <h2 class="fw-bold mb-3">Ansari Intesab</h2> <p class="lead text-muted"> I am a <span class="fw-bold">Full-Stack Web Developer</span> skilled in <strong>MERN Stack</strong>, <strong>DevOps</strong>, <strong>PHP</strong>, <strong>WordPress</strong>, and <strong>Python</strong>. Passionate about building modern, responsive web applications that solve real-world problems. </p> <hr class="my-4"> <h4 class="mb-3">Core Skills</h4> <div class="row"> <div class="col-md-6 text-start"> <ul class="list-unstyled"> <li>MongoDB, Express, React, Node</li> <li>DevOps & CI/CD Workflows</li> <li>Mobile Apps</li> </ul> </div> <div class="col-md-6 text-start"> <ul class="list-unstyled"> <li>PHP & Python Development</li> <li>WordPress Themes & Plugins</li> <li>Modern Web Security</li> </ul> </div> </div> <a href="https://intesab.live" target="_blank" class="btn btn-primary btn-lg mt-4 shadow"> 🌐 Visit My Portfolio </a> </div> </div> </div> </div> </section>

File Name: views/layout.jsx

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>My News Website</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"> <link rel="stylesheet" href="/css/style.css"> <script defer src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script> </head> <body> <nav class="navbar navbar-expand-lg navbar-dark bg-dark"> <div class="container"> <!-- Brand left --> <a class="navbar-brand fw-bold" href="/">📰 News Hub</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <!-- Nav items right --> <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav ms-auto mb-2 mb-lg-0"> <li class="nav-item"><a class="nav-link" href="/">Home</a></li> <li class="nav-item"><a class="nav-link" href="/category/business">Business</a></li> <li class="nav-item"><a class="nav-link" href="/category/technology">Technology</a></li> <li class="nav-item"><a class="nav-link" href="/category/sports">Sports</a></li> <li class="nav-item"><a class="nav-link" href="/category/health">Health</a></li> <li class="nav-item"><a class="nav-link" href="/about">About Me</a></li> </ul> </div> </div> </nav> <div class="container my-4"> <%- body %> </div> <footer class="bg-dark text-light text-center py-3"> <p>© 2025 My News Hub | Created By Ansari Intesab</p> </footer> </body> </html>

Output Preview : Node.js News Website


Features:

  • Node.js + Express with MVC structure
  • News API Integration with error handling
  • Fallback JSON when API is down
  • Bootstrap 5 UI with responsive cards and modern shadows
  • EJS Templates for reusable header & footer
  • About Me Page integrated with personal portfolio
Last updated on