CodyBugstein
CodyBugstein

Reputation: 23342

What is the best way to conditionally serve static files in Express?

I'm building an application that has two separate parts to it, which on the frontend I am building as two separate Angular apps. I am doing it this way so that I can better divide control access to he codebase and not unnecessarily give some team members access to code they do not need.

So there are two separate applications, served from the same NodeJS server. The app that is served depends on whether the user is logged in. If they are a guest user, they get one version app, if they are registered user they get a privileged version of the app with more features.

How can I conditionally/dynamically serve static files in Express, so as to say, "if User1 is a guest, serve Application A, otherwise serve Application B"?

Upvotes: 4

Views: 3815

Answers (1)

Mark McKelvy
Mark McKelvy

Reputation: 3536

If it's just one file you're talking about serving (e.g. app-1.js or app-2.js) then you don't need express.static. You can just handle the request in a normal route handler with res.sendFile like so:

app.get('/get-app', function(req, res) {
  if (userIsLoggedIn()) {
    res.sendFile('/path-to-logged-in-app.js')
  } else {
    res.sendFile('/path-to-logged-out-app.js')
  }
})

More about res.sendFile here.

If you want to serve multiple files via express.static, you'll need two instances of express.static middleware, and another piece of middleware on top of that to modify the request url depending up on the user's logged in status. Maybe something along the lines of the following:

// Middleware function to modify the request url based on user's status
function checkUser(req, res, next) { 
 if (userIsLoggedIn()) {
    req.url = `/app-1/${req.url}`
  } else {
    req.url = `/app-2/${req.url}`
  }

  next()
}

// Set up the middleware stack
app.use(checkUser)
app.use('/app-1', express.static(path.join(__dirname, 'app-1')))
app.use('/app-2', express.static(path.join(__dirname, 'app-2')))

More about writing your own middleware here. You also might want to add some logic in checkUser to only prepend to urls requesting static files (e.g. request urls to /assets/foo.js get the prepend treatment but requests to /api/some-api-function do not).

All that said, I'm not that familiar with Angular but I'd suggest investigating other ways to serve logged in / logged out content. I'm assuming there is some concept of components or "views" in Angular, and it's probably a lot cleaner to just render a "LoggedIn" or "LoggedOut" component/view vs. sending a whole different "app".

Upvotes: 10

Related Questions