How to create dynamic subdomains for each user using node express?

10,670

Solution 1

If using Node.js with Express.js, then:

router.get('/', function (req, res) { 
    var domain = req.get('host').match(/\w+/); // e.g., host: "subdomain.website.com"
    if (domain)
       var subdomain = domain[0]; // Use "subdomain"
    ...
});

Solution 2

// you can use this implementation to get subdomain dynamically
// Use below code to get your subdomain name
// get your dynamic subdomain

app.use((req, res, next) => {
  if (!req.subdomains.length || req.subdomains.slice(-1)[0] === 'www') return next();
  // otherwise we have subdomain here
  var subdomain = req.subdomains.slice(-1)[0];
  // keep it
  req.subdomain = subdomain;
  next();
});


// conditional render a page
app.get('/', (req, res) => {
  // no subdomain
  if (!req.subdomain) {
    // render home page
    // mydomain.com
    res.render('home');
  } else {
    // render subdomain specific page
    // mypage.mydomain.com
    res.render('mypage');
  } // you can extend this else logic to render the different subdomain specific page
});


> Note: to test this locally. you can use Nginx reverse proxy to forward your test url req to your local server and do not forget to point your test url to your local host 127.0.0.1 in your hosts file of your machine

Solution 3

I got here because I wanted to do exactly what OP asked:

On signup, I want to give user his profile and application at username.example.com

The previous answers are ways to handle incoming requests from the already provisioned subdomains. However, the answers led me to thinking what I want is actually really straightforward - here goes:

// Creating the subdomain

app.post('/signup', (req, res) => {
  const { username } = req.body;

  //... do some validations / verifications
  // e.g. uniqueness check etc

  res.redirect(`https://${username}.${req.hostname}`);
})

// Handling requests from the subdomains: 2 steps
// Step 1: forward the request to other internal routes e.g. with patterns like `/subdomain/:subdomain_name/whatever-path`

app.use((req, res, next) {

  // if subdomains
  if (req.subdomains.length) {

    // this is trivial, you should filtering out things like `www`, `app` or anything that your app already uses.

    const subdomain = req.subdomains.join('.');

    // forward to internal url by reconstructing req.url

    req.url = `/subdomains/${subdomain}${req.url}`
  }
  return next()
});

// Handling requests from the subdomains: 2 steps
// Step 2: Have router setup for handling such routes
// you must have created the subdomainRoutes somewhere else

app.use('/subdomains/:subdomain', subdomainRoutes)

Hope it helps.

Share:
10,670
Admin
Author by

Admin

Updated on June 05, 2022

Comments

  • Admin
    Admin about 2 years

    On signup, I want to give user his profile and application at username.example.com I have already created wild-card dns at my domain provider website.

    How can I do that?

  • Arian Faurtosh
    Arian Faurtosh about 9 years
    Can you explain what /\w+/ is doing?
  • eddie
    eddie about 9 years
    /\w+/ is a regex that matches the first word. e.g. "hello.world.com".match(/\w+/)[0] returns 'hello'
  • Ashh
    Ashh over 5 years
    What after this var subdomain = domain[0]?
  • eddie
    eddie over 5 years
    @AnthonyWinzlet req.get('host') contains the full URL path. domain[0] is just an example of how to extract the first part of the URL.
  • Ashh
    Ashh over 5 years
    So what I will have to do with that? How can I create a dynamic subdomain with it?
  • eddie
    eddie over 5 years
    @AnthonyWinzlet in this context, you already configured your network so that express.js get the incoming requests, so now using the "subdomain" you can send different data to different users. E.g., if (subdomain === "john") res.send("Hello John"); else res.send("Hello unknown user");
  • Extrange planet
    Extrange planet about 2 years
    Ok, but .... How could I point all subdomains to Node js express server?
  • eddie
    eddie about 2 years
    That is not on node.js side, but rather on network. E.g., with a reverse proxy as nginx you can route all networks request to the node instance.