nodejs ExpressJS routes only working for index

Go To


I have routes in separate folder for expressjs. The setup is working fine for the 'index' page, but not for any additional routes.

This is my index.js, inside my routes folder.

 module.exports = function(db) {

    return {
        index: function(req, res, next) {

This is my join.js, inside my routes folder.

 module.exports = function(db) {

    return {
        join: function(req, res, next) {

In my app.js, I define my routes like this:

          var routes = require('./routes')(db);
          app.get('/', routes.index);
          app.get('/join', routes.join);

When I go to http://localhost:3000 but when I go to http://localhost:3000/join i get Cannot GET /join

If I define my route for join like this:

 app.get('/join', function(req, res){
     res.send('join 2');

This works.

Any idea what I'm doing wrong here?

Thank you!

2012-04-03 20:24
by dzm


I was having a similar problem, but then remembered this is all "just javascript" and was able to muddle out an answer.

If you want to have your routes defined in multiple files (instead of cramming them all into one routes/index.js file) you can just build the routes object in a hackish way (as follows):

var express = require('express')
  , routes = {
       index: require('./routes').index
     , events: require('./routes/events.js').events
  , hbs = require('hbs');

NOTE: You don't need the express and hbs definitions (first and last lines) in there, I just put it in there to give you a little context. This code snippet came directly from the top of my app.js file.

Notice the .index and .events chained onto the require() function calls. That's the key. My events.js file only has one export (events): = function(req, res){
  console.log('in events');
  res.render('events', { events: events, title: "EVENTS" });
  console.log('events done');

Since the require() function essentially grabs a file and requires (imports) any non-private vars (that is, those attached to the special exports object) and exposes them to the file containing the require() call, I'm able to just grab the specific function I'm requiring from the file I'm including with the require() call. If I had multiple exports defined in the required file, I imagine I could grab them like so (have not tested):

routes = {
    index: require('./routes').index
  , events: require('./routes/events.js').events
  , favorites: require('./routes/events.js').favorites
  , upcoming: require('./routes/events.js').upcoming

I suspect that this would give someone with a bunch of nodeJS or MVC experience an aneurysm if they read your code (I'm betting that it would include the same file 3 times, but I'm not really sure). Maybe better off to do:

routes = {
    index: require('./routes').index
  , events: require('./routes/events.js').events
  , favorites: require('./routes/favorites.js').favorites
  , upcoming: require('./routes/upcoming.js').upcoming

Otherwise, why not just shove them all in index? Not really sure though, this is only my second day working with Node and any of its related technologies...

Also will probably help you if you throw a console.log statement right after your var declarations:

2012-04-10 21:12
by cmcculloh
+1 "but then remembered this is all "just javascript" and was able to muddle out an answer." !! Fabulous answer : - ta-run 2013-01-11 08:33
"Modules are cached after the first time they are loaded" - Asa Ayers 2013-09-04 20:29


The reason why the routes/index.js file works and your routes/join.js does not is because of Node's module loading rules. Check out the docs for modules/folders as modules

It says that it will try to load these files in order. package.json, index.js, index.node.

You can change the file it loads by creating a package.json file in the directory. Set the main property to the name of the new file.

An example of how to make the routes work the way you want is on another question.

2012-04-21 18:09
by Jason


I tested a similar scenario and it worked for me.

I'm guessing the mistake is probably in your routes.js file. You are likely doing:

routes.index = require('./index')(db);
routes.join = require('./join')(db);

Maybe you forget to call the method for join, just doing require(./join). Just a guess.

2012-04-04 07:39
by mihai


if you just say

var routes = require('./routes')

By default, node will start looking for the index file (whether it's index.js or index.node). If you want to use your join file, you will need to explicitly say it:

var join = require('./routes/join')

Now i think join.join should work.

2014-04-03 18:46
by user2393426


Had similar problem.

Only my "/" route worked. When trying to create "/about" i would get an 404 error.

Turns out when I used express-generator it wrote:

app.use('/about', ...etc )

Instead it should have been:

app.all('/about', ...etc )

i Know its not the exact same problem but this is for the strays who find themselves here looking for the same question to the "only index works..." problem.

2016-09-06 19:42
by Ejnaren