Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you handle trailing slashes in next.js routes?

Tags:

next.js

I am trying to set up a next.js app, but I'm having trouble handling routes with a trailing slash. So, for example, if I have a pages structure like this:

pages
 - index.js
 - blog
   - index.js
   - [slug].js

then going to / gives me the base index.js, going to /blog gives me blog/index.js, and going to /blog/my-post gives me blog/[slug].js — so far so good.

But going to /blog/ gives me a 404 error, and there appears to be no way at all to handle this without entirely replacing the next.js router—I can't even redirect /blog/ to /blog. Is there any way around this, or do I need a custom router? Is there a way to extend the next.js router in a way that will let me handle these, without entirely replacing it?

like image 599
futuraprime Avatar asked Jul 12 '19 10:07

futuraprime


2 Answers

There is an option with Next.js 9.5 and up.

In next.config.js, add the trailingSlash config:

module.exports = {
  trailingSlash: true,
}

Source: Trailing Slash

like image 132
Alan Avatar answered Jan 08 '23 05:01

Alan


UPDATE: If you are using next export than you can solve the issue by adding exportTrailingSlash to your next.config.js

As of this writing, there seems to be no way to solve this issue without defining your own custom server.

Previous answer:

You must create a new file blog.js shown bellow:

enter image description here

With the following server.js

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

const PORT = process.env.PORT || 3000;

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

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

    server.get('/blog', (req, res) => {
      const actualPage = '/blog'
     // const queryParams = { title: req.params.id }
      app.render(req, res, '/blog', {})
    })
    server.get('/blog/:id', (req, res) => {
      const actualPage = '/blog/[id]'
      const queryParams = { title: req.params.id }
      app.render(req, res, actualPage, queryParams)
    })

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

    server.listen(PORT, err => {
      if (err) throw err
      console.log(`> Ready on http://localhost:${PORT}`)
    })
  })
  .catch(ex => {
    console.error(ex.stack)
    process.exit(1)
  })

node server.js should start your server and you would have the mapping that you need.

Note, blog/index.js is not used in this example.

like image 43
eenagy Avatar answered Jan 08 '23 04:01

eenagy