node.jsexpressejs

How do I render .ejs files without having to create a route for each one?


Server:

import express from 'express';
const app = express();
app.set('views', './public');
const PORT = 3002;

app.get('/', (req, res) => {
  res.render('index.ejs', { title: 'Page Title'});
});


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

I want to create a link in index.ejs to page2.ejs and have Express.js render page2.ejs without having to create a route for each page in app.js as:

app.get('/page2.ejs', (req, res) => {
  res.render('page2.ejs');
});
app.get('/page3.ejs', (req, res) => {
  res.render('page3.ejs');
});
app.get('/page4.ejs', (req, res) => {
  res.render('page4.ejs');
});

Solution

  • It would be:

    const viewDir = path.join(__dirname, 'view');
    
    app.get('/', ...);
    
    app.get('/*', (req, res, next) => {
      const viewPath = path.join(viewDir, req.path + '.ejs');
    
      if (viewPath.startsWith(viewDir) && fs.existsSync(viewPath)) {
        res.render(viewPath);
      } else {
        next();
      }
    });
    

    viewPath.startsWith(viewDir) check prevents from accessing files outside the expected location.