为什么 Next.js 静态导出应用在 Nginx 上路由失效?

关于Nextjs静态导出路由刷新后不生效的问题。

背景:
1、初始化一个项目,添加一个路由/test
2、配置静态导出:output: "export"

本地run dev访问:localhost:3000/test是可以保持住页面的。
部署到nginx上访问/test是跳到首页的,这个是什么问题?

nginx是有配置404跳转首页的:

  location / {
        try_files $uri $uri/ /index.html;
    }

这个配置vue history模式也是能保持住的。所以现在是啥问题啊?如何才能实现静态化部署后访问路由的问题。

阅读 1.2k
avatarAI BotBETA

在Next.js静态导出应用中,如果你遇到在Nginx上路由失效(即访问特定路由时跳转回首页)的问题,这通常与Nginx的配置方式有关,特别是当Nginx配置为对404错误进行重定向到index.html时。这种配置方式虽然适用于单页面应用(SPA)如Vue或React的路由控制(在客户端),但在Next.js静态导出的情况下可能会导致问题,因为Next.js静态导出会生成实际的HTML文件来对应每个路由。

问题原因

  1. Nginx的try_files指令:这个指令尝试按顺序查找文件或目录,如果所有文件或目录都不存在,则执行最后的/后的URI(这里是/index.html)。在Next.js静态导出中,如果请求的是/test并且Nginx没有直接找到对应的/test.html(或其他对应的静态文件),它就会回退到/index.html,导致显示首页而不是/test页面。

解决方案

方案一:修改Nginx配置以匹配Next.js静态文件

确保Nginx配置能够直接匹配并服务Next.js静态导出的文件。你可以通过修改Nginx配置来优先查找静态文件目录(例如_next/static和输出目录中的.html文件):

server {
    listen 80;
    server_name yourdomain.com;

    location / {
        # 优先查找静态文件
        root /path/to/your/nextjs/output;
        try_files $uri $uri/ /index.html;
    }

    # 如果需要处理静态资源文件(如图片、字体等)
    location /_next/static {
        alias /path/to/your/nextjs/output/_next/static;
        try_files $uri =404;
    }
}

注意:这里/path/to/your/nextjs/output需要替换为你的Next.js项目静态导出后的实际路径。

方案二:使用Next.js的trailingSlash配置

next.config.js中设置trailingSlashtruefalse,这取决于你的路由和Nginx配置。确保你的URL格式与Nginx和Next.js配置相匹配。

// next.config.js
module.exports = {
  trailingSlash: true, // 或 false,取决于你的需求
  exportTrailingSlash: true, // 确保在静态导出时也考虑这个选项
};

方案三:确保Next.js静态导出正确

运行next export确保所有路由都被正确导出为静态HTML文件。检查输出目录中是否存在test.html等文件。

总结

主要问题是Nginx的try_files指令在处理Next.js静态导出时可能不够灵活,因为它默认会回退到index.html。通过调整Nginx配置来更精确地匹配静态文件,或修改Next.js的配置来确保URL格式的一致性,可以解决这个问题。

1 个回答

不是很清楚 next.js 的具体做法,但是技术上来讲,如果你生成的静态目录里没有对应的文件,使用 nginx fallback 到 index.html,看起来是符合预期的结果。

我猜测有几个解决问题的思路:

  1. next.js 是否有 SPA 的构建选项
  2. 缺失的文件指向 404
  3. 使用 next.js 服务器提供服务,nginx 代理
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏