5

I'm trying to use the Express Router with Next.js using their custom-express-server example as my boilerplate. The only difference is that I'm trying to define the routes externally on routes/router.js as follows:

Code in server.js:

const express = require('express')
const next = require('next')

const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
const routes = require('./routes/router')

app.prepare()
  .then(() => {
    const server = express()

    server.use('/', routes)

    server.get('*', (req, res) => {
      return handle(req, res)
    })

    server.listen(port, (err) => {
      if (err) throw err
      console.log(`> Ready on http://localhost:${port}`)
    })
  })

module.exports = app;

Code in routes/router.js:

const express = require('express'),
app = require('../server.js'),
router = express.Router();

router.get('/a', (req, res) => {
  return app.render(req, res, '/b', req.query)
})

router.get('/b', (req, res) => {
  return app.render(req, res, '/a', req.query)
})

router.get('/posts/:id', (req, res) => {
  return app.render(req, res, '/posts', { id: req.params.id })
})

module.exports = router;

At this point, even when I'm importing "app" from server.js, app is not available within router.js.

Is my logic incorrect? If it's not, then why is app not available within router.js?

2 Answers 2

2

You might also try using next-routes, which I use on all of my Next project:

// server.js
const { createServer } = require('http');
const next = require('next');
const routes = require('./routes');

const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handler = routes.getRequestHandler(app);

app.prepare().then(() => {
    createServer(handler).listen(port, err => {
        if (err) {
            throw err;
        }
        console.log(`> Ready on http://localhost:${port}`);
    });
});

Then you can configure your routes in the routes.js file without accessing the app:

// routes.js

const nextRoutes = require('next-routes');
const routes = (module.exports = nextRoutes());

routes
    .add('landing', '/')
    .add('blog', '/blog', 'blog')
    .add('blog-post', '/blog/:postId', 'blog')

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your suggestion, @ForrestLyman. I also considered next-routes as a solution, but I was tied to express due to the many express middlewares that this project requires.
1

Just solved it. This issue is known as a circular dependency, and it should be avoided at all costs... unless the pattern you're using (like the boilerplate I used, I guess...) requires it.

To solve it, just export from file "A" the dependency that file "B" uses before you require file "B" on file "A".

...And that's it pretty much.

1 Comment

Can you provide a code snippet example of your solution? I've tried what you said and it didn't help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.