66

I am used to working on httpd ( Apache ) which provides a way to configure subdomains which is mapped to a directory. How can I do the same thing in Connect.js/Express.js ? I see that the only thing that I have is routes which I am not sure how I can use to configure sub domains. I have subdomains like m.mysite.com, sync.mysite.com

Can someone help ?

Grace Huang
  • 5,355
  • 5
  • 30
  • 52
Raks
  • 1,723
  • 3
  • 18
  • 26

6 Answers6

140

Or alternatively you could use vhost.

Then, create several sites in their own directory and export the express app, eg. /path/to/m/index.js:

var app = express()
/* whatever configuration code */
exports.app = app
// There is no need for .listen()

And then handle all requests with the following app:

var vhost = require('vhost');

express()
.use(vhost('m.mysite.com', require('/path/to/m').app))
.use(vhost('sync.mysite.com', require('/path/to/sync').app))
.listen(80)

Note that /path/to/m and /path/to/sync can be absolute paths (as written above) or relative paths.

Daniel Node.js
  • 6,734
  • 9
  • 35
  • 57
Adrien
  • 9,551
  • 3
  • 26
  • 27
29

You could append a subdomain to a request and then check for it in subsequent next() calls.

I got the following code from > http://groups.google.com/group/express-js/browse_thread/thread/b04bbaea7f0e8eed (so full credit to the original author)

app.get('*', function(req, res, next){ 
  if(req.headers.host == 'some.sub.domain.com')  //if it's a sub-domain
    req.url = '/mysubdomain' + req.url;  //append some text yourself
  next(); 
});

// This will mean that all get requests that come from the subdomain will get 
// /subdomain appended to them, so then you can have routes like this 
app.get('/blogposts', function(){ 
  // for non-subdomain 
});

app.get('/mysubdomain/blogposts', function(){ 
   // for subdomain 
});
BishopZ
  • 6,269
  • 8
  • 45
  • 58
neebz
  • 11,465
  • 7
  • 47
  • 64
14

I have recently came across this problem, and wrote a module to help with it using express 4. https://www.npmjs.org/package/express-subdomain.

Example - api subdomain.

var express = require('express');
var app = express();

var router = express.Router();

//api specific routes
router.get('/', function(req, res) {
   res.send('Welcome to our API!');
});

router.get('/users', function(req, res) {
    res.json([
        { name: "Brian" }
    ]);
});

app.use(subdomain('api', router));
app.listen(3000);

Check out the module on npm to see more examples.

bmullan91
  • 549
  • 5
  • 7
  • 4
    This seems to just specify routes for the subdomain — how do you specify routes for the root domain again? – fatuhoku Feb 09 '16 at 16:23
  • Im trying this module, but idk how to use a subdomain on port 80 without setting it up in IIS. I want to keep my main site on 80 but add subdomain for my express node api. – M H Sep 02 '18 at 05:07
7

I created a module to help with subdomains in Express: https://github.com/WilsonPage/express-subdomain-handler

wilsonpage
  • 17,341
  • 23
  • 103
  • 147
  • Hi, your subdomain-handler looks interesting. How would I use this with say "dev.localhost"? What else would I need to change besides "baseUrl:localhost", it's not very clear from the example you posted. Thanks. – braitsch May 20 '12 at 04:35
  • If you are using it locally you will have to make sure that the subdomain you are using is listed inside your machine's 'hosts' file. When in production you can setup wildcard subdomains so that you dont have to list every subdomain you need. I usually use the format: subdomain.mysite.dev (locally) and subdomain.mysite.com (in production). – wilsonpage May 20 '12 at 10:13
2

Do as I say, create two express app in different folder.

For example: one app in /blogsite directory

const express = require("express");

const blog = express();

blog.get("/", (req, res) => {
 res.send("BLOG SECTION");
});

blog.get("/allblogs", (req, res) => {
 res.json([
  { title: "csgo major boston", description: "Best CSGO major ever" },
  { title: "Blast pro series", description: "Coolest series of CSGO" },
 ]);
});

module.exports = { blog };

and another one in /portfolio directory

const express = require("express");

const portfolio = express();

portfolio.get("/", (req, res) => {
 res.send("PORTFOLIO SECTION");
});

portfolio.get("/resume", (req, res) => {
 res.send("HERE'S MY RESUME");
});

module.exports = { portfolio };

Now create a main app in the outer folder and import the other two express apps that you just made in /blogsite directory and /portfolio directory.

And in the main app do this,

const express = require("express");
const vhost = require("vhost");

const { blog } = require("./blogsite");
const { portfolio } = require("./portfolio");

const app = express();

// BLOG AND PORTFOLIO

// url: http://blog.localhost:3002/
// url: http://blog.localhost:3002/allblogs

// url: http://portfolio.localhost:3002/
// url: http://portfolio.localhost:3002/resume

app
 .use(vhost("portfolio.localhost", portfolio))
 .use(vhost("blog.localhost", blog));

// MAIN APP ROUTES OR ENDPOINTS

// url: http://localhost:3002
// url: http://localhost:3002/myhobbies

app.get("/", (req, res) => {
 res.send("MAIN APP SECTION");
});

app.get("/myhobbies", (req, res) => {
 res.send("MAIN APP -> myhobbies section");
});

app.listen(3002, () => {
 console.log("started listening");
});

fileStructure at the end should be looking like this

main(folder)
  index.js (main express app which you need to run using node or nodemon)
  blogsite(folder that I talked about for blog.localhost)
    index.js (blog express app)
  portfolio(folder)
    index.js (portfolio express app)
0

I've had this exact same requirement for a project I was working on and ended up throwing together a middleware-based solution. It allows you to define routers and view folders per subdomains.

Check it out on NPM https://www.npmjs.com/package/express-multiview or GitHub https://github.com/daryl-cecile/express-multi-view#readme

Daryl
  • 11
  • 1