Creating a versatile Express Router that can serve multiple websites by utilizing conditional routes based on the domain name

Instead of suggesting changes to my application architecture, I am seeking practical solutions for my specific requirements. I have code that serves different static files based on the domain name, allowing me to run multiple static HTML sites from the same routes:

    app.get('/', (req, res) => {
      console.log('req.hostname: ', req.hostname)
      if (req.hostname === 'localhost') {
        app.use(express.static(path.join(__dirname, 'pages/site-A/')));
        res.sendFile(path.join(__dirname, 'pages/site-A/index.html'));
      } else {
        app.use(express.static(path.join(__dirname, 'pages/default/')));
        res.sendFile(path.join(__dirname, 'pages/default/index.html'));
      }
    });

While this setup works well, I need to integrate a more complex site management feature into the main site. This site has its own router, typically called like so:

    app.use('/', require('pages/site/routes'));

My challenge is how to conditionally use the router file in the '/' route depending on the domain name. Here is what I have so far:

    app.get('/', (req, res) => {
      console.log('req.hostname: ', req.hostname)
      if (req.hostname === 'localhost') {

        app.use(express.static(path.join(__dirname, 'pages/site-A/')));
        res.sendFile(path.join(__dirname, 'pages/site-A/index.html'));

      } else if (req.hostname === 'other.local') {

        // Need to find equivalent of applying router using app.use('/') here

      } else {

        app.use(express.static(path.join(__dirname, 'pages/default/')));
        res.sendFile(path.join(__dirname, 'pages/default/index.html'));

      }
    });

Answer №1

After researching subdomain routing examples in NodeJS, I decided to implement a similar principle.

I created a middleware function that allows you to specify a hostname and the corresponding route. If there is a match, the desired result is returned; otherwise, it moves to the next step using next();

module.exports =
  (hosts, customRouter) => {
    return (req, res, next) => {
      let host = req.headers.host ? req.headers.host : ''; // hostname provided in headers

      const isHost = (host && hosts.includes(host)); // check if requested host is in array of custom hostnames
      if (isHost) {
        return customRouter(req, res, next);
      }

      next();
    }
  };

In my main express server, I import this function:

const forwardForDomain = require('./domainRouting');

Then I can use it to specify domain names to access specific routes or sites.

app.use(
  forwardForDomain(
    [
      'localhost',
      'site-a.local'
    ],
    require('./pages/site-A/routes')
  )
);

This setup enables me to easily manage multiple sites with different domain names for development and production purposes. By modifying the /etc/hosts file to point .local domains to the server during development, I can seamlessly switch between environments.

app.use(
  forwardForDomain(
    [
      'site-a-domain.com',
      'site-a.local'
    ],
    require('./pages/site-A/routes')
  )
);

app.use(
  forwardForDomain(
    [
      'site-b-domain.com',
      'site-b.local'
    ],
    app.use(express.static(path.join(__dirname, 'pages/site-b-html/')))
  )
);

var reactInterfaceC = require('./pages/site-c/routes')
app.use(
  forwardForDomain(
    [
      'site-c-domain.com',
      'site-c.local'
    ],
    reactInterfaceC
  )
);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Trouble with CSS and JS tabs not activating when clicked?

I am experiencing issues with a navigation (organized in tabs) that is not functioning on this page, but it works correctly on this page using the same method for inclusion. When clicking "Norway" on the top left, the navigation opens but switching to the ...

React - Login page briefly appears while loading

Hello, I have built a React application that consists of a Login page, Loading page, and the main app itself. However, there is a small issue where after a user logs in, instead of smoothly transitioning to the Loading page until the data is loaded, the L ...

Failure to display JavaScript variables within a div element

I'm having trouble displaying my JavaScript variable inside a div column. The value is not showing up, even when I use the inspector tool. However, if I display it outside of any div tags, at the top of the page, it works fine. $(document).ready(fu ...

Limiting the length of parameters in an Angular directive

Is there a character limit for the parameter being sent to this directive? I'm encountering an issue with my code: header = JSON.stringify(header); columnObj = JSON.stringify(columnObj); $compile('<div column-filter-sort header=' + heade ...

Ways to stringify a JavaScript new date object using JSON

Extracting information from the form's JSON as users input data on the calendar const data = JSON.stringify(orderForm.informationDate)); At present, I am retrieving JSON data to generate a PDF document: {"year":2023,"month":12,&qu ...

I am seeking to showcase an image in a window, and upon the image being clicked, execute the code in a separate window

I am looking to showcase the image provided below. <img src="http://gfx.myview.com/MyView/skins/livesample/image/livesample.gif" alt="" border="0"><a/> Once the image is clicked, I want it to execute the following code. How can I ensure that ...

Adding a sign at the center of a map in React-Leaflet

One of the features I added to the map is a center indicator sign. <MapContainer fullscreenControl={true} center={center} zoom={18} maxNativeZoom = {22} maxZoom={22} classNa ...

Utilize an RxJS observable within a standard Express.js middleware function

Challenges arise as I navigate through RxJS in my project. The observable getSettings(req) is a crucial element that I wish to incorporate into a regular express.js middleware function, like so: middleware(req, res, next) { ... const settings = getSett ...

Custom options in MUI Autocomplete are not displaying the selected option

I am currently implementing MUI v5's Autocomplete for a dropdown feature on my website. Within this dropdown, I have options that include both a title and an id. My goal is to store the selected option's id in the state while also updating the d ...

Enhanced password encryption on the client side using jQuery ajax and PHP [advanced technique]

I found a solution here on how to encrypt data in javascript and decrypt it on the server side. I am encountering an issue while trying to implement this with my ajax form submission. I attempted to integrate it into my code snippet below, but it's no ...

The issue of accessing the session before scripts are loaded arises when using VueJS alongside Firebase Authentication

Currently grappling with a project where I'm facing some challenges... I've opted for VueJS on the frontend and implemented Firebase Authentication for user login. I'm trying to determine the login status of a user by using firebase.auth(). ...

When working with NodeJS and an HTML form, I encountered an issue where the 'Endpoint'

Having trouble sending input data from a form to my nodejs endpoint. When I try printing the req.body, it shows up as undefined and I can't figure out why. Here is the relevant API code snippet: var bodyParser = require('body-parser') var e ...

Navigating to the parent node in a treeview within the wijmo flex grid: a step-by-step guide

Utilizing the wijmo flex grid, I've successfully created a tree view for my data. I can determine if a specific node has children and its level, but I'm struggling to navigate to the parent node from a given one. Additionally, I am able to retrie ...

Saving data in memory using Node.js

In my Node.js application, I am making a request to retrieve a value and I want to store this returned value in memory. Additionally, I need the value to be initialized when the app starts. What is the best way to accomplish this in Node.js? ...

How come the default is operating when the number is specifically set to 1?

let spans = document.querySelector(`#spans`); let hrs = document.querySelector(`#hrs`); let mins = document.querySelector(`#mins`); let secs = document.querySelector(`#secs`); let start = document.querySelector(`#start`); let stop = document.querySelector( ...

Rendering children using props within the parent container on every child component

I am currently facing an issue while creating a side menu that is supposed to render children within it. The problem occurs when each child gets wrapped in the entire render output of the side menu, and I am struggling to find a solution for this. Even wi ...

I am having trouble running a Python script within an Express application

I have a Python script that turns on an LED on my Raspberry Pi, and I want to execute it when a button is clicked on my Express app. I've tested the script and it works fine, but for some reason, when I try to run it from the server, it doesn't w ...

Capture - retrieve the data of the specified route using a specific keyword

Query I am managing multiple nested routers and I need to retrieve the entire string that corresponds to the request's path. To clarify, please refer to this code snippet: const express = require('express') const app = express() const rout ...

Retrieving information within the iteration

I am facing an issue with connecting to an external server named Pexels in order to retrieve photos from node.js. The problem seems to be related to JavaScript, as Pexels limits the user to download up to 40 pictures per page. https://api.pexels.com/v1/cu ...

Ways to consolidate multiple API requests on a single page without relying on the promise package

I am currently working on incorporating 2 APIs into a single page using Nodejs. I have done some research and found suggestions to use the promise package, but it seems that package is deprecated now. Can someone please guide me on how to achieve this? ...