Preview:
npm init -y
npm install express ejs node-fetch

project-folder/
├── views/
│   └── posts.ejs
├── app.js

app.js

const express = require('express');
const fetch = require('node-fetch');
const app = express();
const PORT = 3000;

// Set EJS as the view engine
app.set('view engine', 'ejs');

// Route to fetch API data and render
app.get('/', async (req, res) => {
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/posts');
    const posts = await response.json();

    res.render('posts', { posts: posts.slice(0, 5) }); // limit to 5 posts
  } catch (error) {
    res.status(500).send('Error fetching data');
  }
});

app.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}`);
});


views/posts.ejs

<!DOCTYPE html>
<html>
<head>
  <title>Posts Table</title>
  <style>
    table {
      width: 80%;
      border-collapse: collapse;
      margin: 20px auto;
    }
    th, td {
      padding: 10px;
      border: 1px solid #ccc;
      text-align: left;
    }
    th {
      background-color: #f4f4f4;
    }
  </style>
</head>
<body>
  <h2 style="text-align:center;">Posts from API</h2>
  <table>
    <thead>
      <tr>
        <th>ID</th>
        <th>Title</th>
        <th>Body</th>
      </tr>
    </thead>
    <tbody>
      <% posts.forEach(post => { %>
        <tr>
          <td><%= post.id %></td>
          <td><%= post.title %></td>
          <td><%= post.body %></td>
        </tr>
      <% }) %>
    </tbody>
  </table>
</body>
</html>
downloadDownload PNG downloadDownload JPEG downloadDownload SVG

Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!

Click to optimize width for Twitter