Express: EJS Movie Application
Create an Express.js app using EJS that renders a movie gallery.
- Render a list of movies with titles and ratings.
- Use a layout file with a header/footer and an external CSS file to style the movie cards.
- Highlight movies with a rating above 8 in a different color using conditional rendering.
Directory Structure
First, create the following folder and file structure for your project:
/movie-gallery
├── public/
│ └── css/
│ └── style.css
├── views/
│ ├── layouts/
│ │ └── main.ejs
│ └── movies.ejs
├── app.js
└── package.json
app.js
This file sets up the Express server, defines the movie data, and renders the main page.
import express from 'express';
import path from 'path';
import { fileURLToPath } from 'url';
import ejsMate from 'ejs-mate';
const app = express();
const PORT = 3000;
// Needed for __dirname in ES Modules
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
// Set EJS as the view engine and use ejs-mate for layouts
app.engine('ejs', ejsMate);
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
// Serve static files (like CSS) from the 'public' directory
app.use(express.static(path.join(__dirname, 'public')));
// In-memory movie data
const movies = [
{ title: 'Inception', rating: 8.8 },
{ title: 'The Matrix', rating: 8.7 },
{ title: 'Joker', rating: 8.4 },
{ title: 'Parasite', rating: 8.5 },
{ title: 'Interstellar', rating: 8.6 },
{ title: 'The Avengers', rating: 8.0 },
{ title: 'Forrest Gump', rating: 8.8 }
];
// --- Route ---
// GET /movies - Render the movie gallery page
app.get('/movies', (req, res) => {
res.render('movies', { movies });
});
// Start the server
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}/movies`);
});
EJS and CSS Files
views/layouts/main.ejs
This is the main layout file with the header, footer, and a link to the stylesheet.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Movie Gallery</title>
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<header>
<h1>My Favorite Movies</h1>
</header>
<main>
<%- body %>
</main>
<footer>
<p>© 2025 Movie Gallery</p>
</footer>
</body>
</html>
views/movies.ejs
This file iterates over the movie data and renders each movie card, using the layout file.
<% layout('layouts/main') %>
<div class="gallery-container">
<% movies.forEach(movie => { %>
<div class="movie-card <%= movie.rating > 8 ? 'highlight' : '' %>">
<h2><%= movie.title %></h2>
<p>Rating: <%= movie.rating %></p>
</div>
<% }) %>
</div>
public/css/style.css
This file provides the styling for the movie cards and the highlight effect.
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 0;
text-align: center;
}
header, footer {
background-color: #333;
color: white;
padding: 1rem 0;
}
main {
padding: 1rem;
}
.gallery-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 20px;
}
.movie-card {
background-color: white;
border: 1px solid #ddd;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
width: 250px;
padding: 20px;
}
/* Style for highlighted movies */
.movie-card.highlight {
background-color: #fffbe6;
border-color: #f6e05e;
}
.movie-card h2 {
margin-top: 0;
}
Run and Test
npm init -y
npm install express ejs ejs-mate
Then, ensure your package.json
includes "type": "module"
.
node app.js
Open your web browser and navigate to http://localhost:3000/movies
. You will see a gallery of movie cards. The movies with a rating higher than 8 will have a distinct yellow background, demonstrating the conditional rendering.