New Project Routine

21 Oct 2023

I have a sort of muscle memory for starting little web projects now. I seem to have landed on node/express SSR apps with HTMX sprinkles. So it goes a bit like this:

Express Skeleton

That’s my basic web app setup, but since this is an express app, and we’re using some EJS templating, there’s some other starter files I like to create. Let’s start with our pages. I’ll need an index and a 404 page, and my pages are all going to have a header section as well as a nav and a footer. Something like this:

─── views
    ├── 404.ejs
    ├── index.ejs
    └── partials
        ├── footer.ejs
        ├── head.ejs
        └── nav.ejs

To give you a flavour of how that all works, here’s a sample index.ejs

<!DOCTYPE html>
<html lang="en">
<%- include('./partials/head.ejs') %>
  <body>
    <%- include('./partials/nav.ejs') %>
      <div class="content">
        <h2>Hello world</h3>
      </div>
      <%- include('./partials/footer.ejs') %>
  </body>
</html>

Then we need some basic routing in server.js

const express = require('express');
const app = express();
 
const hostname = '127.0.0.1';
const port = 3000;

app.set('view engine', 'ejs');
app.use(express.static('public'));

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

//404 handling
app.use(function (req, res, next) {
  res.status(404).render('404', { title: '404', url: req.url });
});

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

And, lastly, a bit of CSS to make it beautiful.

@viewport {
    width: device-width ;
    zoom: 1.0 ;
} 

body{
    max-width: 1200px;
    font-family: Tahoma, Arial, Helvetica, sans-serif;
    margin: 0;
}

nav {
    position: fixed; 
    top: 0; 
    width: 100%; 
    overflow: hidden;
    background-color: #EEE;
}

nav li {
    display: inline-block;
    padding: 0;
}

nav a {
    display: inline;
    color: #333;
    text-align: center;
    padding: 17px 8px;
    text-decoration: none;
}

nav a:hover {
    background: #ddd;
    color: black;
}

nav ul {
    padding-inline-start: 4px;
}

/* push content down below the nav bar */
.content {
    padding: 50px 10px 10px 10px;
}

footer {
    width:100%;
    position:absolute;
    bottom:0;
    left:0;
    color: #757171;
    text-align: center;
    margin: 80px auto 20px;
    background-color: #EEE;
}

chefs_kiss.jpg