Home
Support Forums

Angular SSR with Clover Engine and Express on Netlify

Dear Support,

I have still issues with SSR and Express.js after carefully reading the articles. I feel that I just miss a tiny netlify tweak to make that work.

This is the folder structure of my project in VSCode:

The content of the netlify.toml is the following:

[build]
  functions = "./functions"

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

Finally I just have one server.js express app transformed as a Netlify Function which do the easy server side rendering based on the new Angular Clover approach.

server.js content:

const express = require('express');
const { Engine } = require('@nguniversal/common/clover/server');
const { join } = require('path');
const { format } = require('url');
const serverless = require('serverless-http');

// const PORT = 8080;
const DIST = join(__dirname, '..', 'dist', 'apps', 'web');

const app = express();

app.set('views', DIST);

app.get(
  '*.*',
  express.static(DIST, {
    maxAge: '1y',
    fallthrough: false,
  })
);

// Redirect to default locale
// app.get(/^(\/|\/favicon\.ico)$/, (req, res) => {
//   res.redirect(301, `/en-US${req.originalUrl}`);
// });

const ssr = new Engine();
app.get('*', (req, res, next) => {
  ssr
    .render({
      publicPath: DIST,
      url: format({
        protocol: req.protocol,
        host: `angular-ssr-test.netlify.app`,
        // host: `localhost:${PORT}`,
        pathname: req.path,
        query: req.query,
      }),
      headers: req.headers,
    })
    .then(html => res.send(html))
    .catch(err => next(err));
});

// app.listen(PORT, () => {
// console.log(`>>> Node Express server listening on http://localhost:${PORT}`);
// });

// Blog: https://www.netlify.com/blog/2018/09/13/how-to-run-express.js-apps-with-netlify-functions/
// Netlify + Express Apps: https://github.com/netlify-labs/netlify-functions-express
// Source: https://github.com/neverendingqs/netlify-express/blob/0780127cd575704e2a2a00a1a648ba5a5a66c388/express/server.js
app.use('/.netlify/functions/server', express.Router()); // path must route to lambda
module.exports = app;
module.exports.handler = serverless(app);

After deployment and calling the function url, the clover server which run locally well somehow messed up with the /.netlify/functions/server path.

I got the following error after calling this url: https://angular-ssr-test.netlify.app/.netlify/functions/server

Error: ENOENT: no such file or directory, stat '/var/task/dist/apps/web/.netlify/functions/server'

I hope we can ellaborate on this. The localhost version of server.js working well on my machine, I feel that it should also work with Netlify + Express.

Let me now if you have any tips what should I modify above to be compatible with the netlify routing.

Thanks in advance, Attila

Looks like you’re trying to load the current directory and then joining the dist/apps/web to it. This might work locally because the file structure is similar there.

On Netlify the file system is not using the same directory structure. Thus, I am afraid this might not work.

Thanks @hrishikesh good point maybe this is the main problem. I try to restructure and get back to you.

Appreciate for the hint.