如何处理next.js路由中的尾部斜杠?

时间:2019-07-12 10:28:01

标签: next.js

我正在尝试设置next.js应用程序,但是在处理带有斜杠的路由时遇到了麻烦。因此,例如,如果我具有这样的页面结构:

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

然后转到/给我基础index.js,转到/blog给我blog/index.js,转到/blog/my-post给我{{1} } —到目前为止一切顺利。

但是转到blog/[slug].js会给我一个404错误,并且在不完全替换next.js路由器的情况下,似乎根本无法解决这个问题-我什至无法将/blog/重定向到/blog/。有什么解决办法吗,还是我需要自定义路由器?有没有一种方法可以扩展next.js路由器,让我处理它们,而无需完全替换它?

5 个答案:

答案 0 :(得分:2)

Next.js 9.5有一个选项

在next.config.js中,添加TrailingSlash配置:

module.exports = {
  trailingSlash: true,
}

来源:https://nextjs.org/docs/api-reference/next.config.js/trailing-slash

答案 1 :(得分:0)

更新:如果您使用的是next export,则可以通过在exportTrailingSlash上添加next.config.js来解决此问题

在撰写本文时,如果不定义自己的自定义服务器,似乎无法解决此问题。

上一个答案:

您必须创建一个新文件blog.js,如下所示:

enter image description here

使用以下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应该启动服务器,您将拥有所需的映射。

注意,在此示例中未使用blog/index.js

答案 2 :(得分:0)

我没有解决办法。这仍然是一个巨大的问题。但是,在Next.js 9.x.x中,我确实有一个非常可怕的黑客来解决此问题。

在我的/pages/_error.js中,添加了以下代码:

FourOhFour.getInitialProps = ({asPath, res}: any): any => {
    const supportedPaths = [
        '/page1/',
        '/page2/',
        '/page3/'
    ];

    for (let i = 0, l = supportedPaths.length; i < l; i++) {
        const path = supportedPaths[i];
        if (asPath === path) {
            res.writeHead(301, {Location: path.substring(0, path.length - 1)});
            return res.end();
        }
    }

    return {};
};

这将确保所有给定的页面将重定向到正确的路径。

这需要您手动指定所有可能不适合您的页面网址-至少是这样。

答案 3 :(得分:0)

您可以将其添加到您的_app.js文件中

MyApp.getInitialProps = async ctx => {
  const pathAndQueryDivided = ctx.ctx.req.url.split('?');
  if (pathAndQueryDivided[0].endsWith('/')) {
    const urlWithoutEndingSlash = pathAndQueryDivided[0].replace(/\/*$/gim, '');

    ctx.ctx.res.writeHead(301, {
      Location: urlWithoutEndingSlash + (pathAndQueryDivided.length > 1 ? `?${pathAndQueryDivided[1]}` : ''),
    });
    ctx.ctx.res.end();
    return {};
  }
    

  const initialProps = await App.getInitialProps(ctx);

  return {
      ...initialProps,
  };
};
  • App.getInitialProps被称为第一个服务器端
  • 它划分路径和查询参数,因为我们只想知道URL是否以斜杠结尾
  • 询问网址是否以斜杠结尾
  • 它用所有内容代替网址的最后一个斜杠
  • 它会将您重定向到没有斜杠+查询参数的网址

答案 4 :(得分:0)

我已经通过将nginx用于我的生产应用程序来完成了重定向:

rewrite ^(.+)/+$ $1 permanent;