当前位置: 首页 > 知识库问答 >
问题:

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

冯奇思
2024-09-17

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

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

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

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

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

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

共有2个答案

孙梓
2024-09-17

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

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

  1. next.js 是否有 SPA 的构建选项
  2. 缺失的文件指向 404
  3. 使用 next.js 服务器提供服务,nginx 代理
梁丘经艺
2024-09-17

在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格式的一致性,可以解决这个问题。

 类似资料:
  • 问题内容: 我想像通常那样处理静态文件,但像通常那样处理动态路由 其中一位开发人员在此评论中提出了解决方案,但我不清楚他的意思。 问题答案: 好的。我在Express的response object 的源代码中找到了一个示例。这是该示例的稍作修改的版本。 它使用该方法。 注意 :安全性更改要求使用此选项。

  • next.js(app router) 在 ssg(output: "export") 模式下 我的动态路由 /app/live/[id]/page.tsx 可以类似 react-router 那样动态获取么 id 么(useParams),而不是用 generateStaticParams 去生成,因为可能会有数万乃至数 10 万个 id

  • 路由可以让你:

  • 情景: 我已将静态数据放在webroot/*文件夹位置,服务器根据请求提供这些数据。 我有很多路由API的路由。 路由器代码: 文件夹webroot包含以下文件: 索引。css 索引。html 图像/图像。jpg公司 问题: 需要在路由不匹配时提供webroot/index.html文件(它不起作用;返回值**'资源未找到')**:如果我请求 /xyz/abc数据,则应提供webroot/inde

  • 问题内容: 我有一个非常简单的类,想用作另一个类的子类。但是,当我将其代码放入父类时,我得到: 非静态变量,不能从静态上下文中引用 另一方面,当我将sublass 的类代码放在“父母的”类代码之外时,我不会收到此错误。 为什么会这样呢? 问题答案: 嵌套类(顺便说一下,它 不是 子类)没有被标记为静态的,因此它是一个 内部 类,需要构造一个编码类(JavaApp1)的实例。 选项: 使嵌套类静态

  • 我有一个react应用程序(使用react路由器和html5 pushstate路由),我想http://example.com/v2作为我的新网站服务器的基本路径 我使用以下nginx配置: 这是为了捕获 /v2并使用新的js文件 因为对于第一个位置块,即使是404也会被重定向到v2/index.html,所以第二个位置的意图是用扩展来处理uri,所以如果http://example.com/v