Next.js:托管在 AWS Cloudfront 上时,如何使链接与导出的站点一起使用?
Next.js: How to make links work with exported sites when hosted on AWS Cloudfront?
我正在尝试通过执行 Static html export(即 next export
)来获得原型 Next.js 项目,然后将生成的输出复制到 AWS S3 并通过 Cloudfront 提供它.
我在 /pages
目录中有以下两页:
index.tsx
Pricing.tsx
然后,在 routing doco 之后,我从索引页面向定价页面添加了 Link
,如下所示:
<Link href="/Pricing">
<a>Pricing</a>
</Link>
这会导致 link 看起来像 example.com/Pricing
(当您将鼠标悬停在它上面并单击 link 时,页面确实会更改为定价页面和浏览器在 URL 栏中显示 example.com/Pricing
。
问题是,link 不是真实的 - 它不能通过 url 栏直接添加书签或导航到。
问题似乎是当我执行 next export
时,Next.js 为每个页面生成一个 .html
文件,但路由器不使用那些 .html
后缀。
因此,在使用网站时,如果用户尝试添加书签 example.com/Pricing
;稍后加载该书签将失败,因为 Cloudfront 将 return 404(因为 CF 只知道 .html
文件)。
然后我尝试将我的 Link
更改为:
<Link href="/Pricing.html">
<a>Pricing</a>
</Link>
这会导致路由器使用 example.com/Pricing.html
并且在 Cloudfront 上工作正常 - 但它实际上会在本地开发期间导致 404(即使用 next dev
)!
我可以尝试的其他解决方法是重命名所有 .html
文件并删除扩展名,然后再将它们上传到 S3(并确保它们获得 content-type: text/html
header)- 或者引入 Cloudfront lambda,它在请求 .html
资源时即时重命名。我真的不想做 lambda 的事情,但是上传前的重命名应该不会太难。
但感觉我真的在这里工作上坡。我在基本层面做错了什么吗? Next.js linking 应该如何使用静态 html 导出?
Next.js版本:9.5.3-canary.23
写完这个问题后,我找到了一个合理的解决方法 - 虽然我不确定它是否是“正确”答案。
将 Link
更改为:
<Link href="/Pricing" as="/Pricing.html">
<a>Pricing</a>
</Link>
这似乎适用于本地开发人员和为 Cloudfront 服务的站点添加书签。仍然感觉有点靠不住。我也比较喜欢那些非 .html
的网址。哦,好吧,也许我会改用重命名解决方法。
如果您希望您的 URL 是“干净的”并且末尾没有 .html
,则为替代答案。
要使 Next.js 默认 URL 链接与 S3/Cloudfront 正常工作,您必须在 next.config.js
:[=31] 中配置“添加尾部斜杠”选项=]
module.exports = {
trailingSlash: true,
}
export pages as index.html files and require trailing slashes, /about becomes /about/index.html and is routable via /about/. This was the default behavior prior to Next.js 9.
现在您可以将 Link
定义保留为:
<Link href="/Pricing">
<a>Pricing</a>
</Link>
这导致 Next.js 做两件事:
- 使用url
example.com/Pricing/
- 注意最后的/
- 在其自己的目录中将每个页面生成为
index.html
- 例如/Pricing/index.html
许多 HTML 服务器在其默认配置中,如果在 URL 中看到尾随 /
字符,将从匹配目录中提供 index.html
.
S3 也会这样做,如果您将其设置为网站并且 IFF 您可以通过 访问 URL。
因此您的 Cloudfront 分发来源必须配置为 Origin type = Custom Origin
指向类似 example.com.s3-website.us-east-1.amazonaws.com
的域, 而不是 作为 S3 Origin
.
如果您有 Cloudfront/S3 mis-configured,当您点击“尾部斜杠”样式时 URL - 您可能会看到浏览器下载类型为 [=24= 的文件] 包含 0 bytes
.
编辑:根据issue 16617.
,注意包含 .
个字符的页面
我正在尝试通过执行 Static html export(即 next export
)来获得原型 Next.js 项目,然后将生成的输出复制到 AWS S3 并通过 Cloudfront 提供它.
我在 /pages
目录中有以下两页:
index.tsx
Pricing.tsx
然后,在 routing doco 之后,我从索引页面向定价页面添加了 Link
,如下所示:
<Link href="/Pricing">
<a>Pricing</a>
</Link>
这会导致 link 看起来像 example.com/Pricing
(当您将鼠标悬停在它上面并单击 link 时,页面确实会更改为定价页面和浏览器在 URL 栏中显示 example.com/Pricing
。
问题是,link 不是真实的 - 它不能通过 url 栏直接添加书签或导航到。
问题似乎是当我执行 next export
时,Next.js 为每个页面生成一个 .html
文件,但路由器不使用那些 .html
后缀。
因此,在使用网站时,如果用户尝试添加书签 example.com/Pricing
;稍后加载该书签将失败,因为 Cloudfront 将 return 404(因为 CF 只知道 .html
文件)。
然后我尝试将我的 Link
更改为:
<Link href="/Pricing.html">
<a>Pricing</a>
</Link>
这会导致路由器使用 example.com/Pricing.html
并且在 Cloudfront 上工作正常 - 但它实际上会在本地开发期间导致 404(即使用 next dev
)!
我可以尝试的其他解决方法是重命名所有 .html
文件并删除扩展名,然后再将它们上传到 S3(并确保它们获得 content-type: text/html
header)- 或者引入 Cloudfront lambda,它在请求 .html
资源时即时重命名。我真的不想做 lambda 的事情,但是上传前的重命名应该不会太难。
但感觉我真的在这里工作上坡。我在基本层面做错了什么吗? Next.js linking 应该如何使用静态 html 导出?
Next.js版本:9.5.3-canary.23
写完这个问题后,我找到了一个合理的解决方法 - 虽然我不确定它是否是“正确”答案。
将 Link
更改为:
<Link href="/Pricing" as="/Pricing.html">
<a>Pricing</a>
</Link>
这似乎适用于本地开发人员和为 Cloudfront 服务的站点添加书签。仍然感觉有点靠不住。我也比较喜欢那些非 .html
的网址。哦,好吧,也许我会改用重命名解决方法。
如果您希望您的 URL 是“干净的”并且末尾没有 .html
,则为替代答案。
要使 Next.js 默认 URL 链接与 S3/Cloudfront 正常工作,您必须在 next.config.js
:[=31] 中配置“添加尾部斜杠”选项=]
module.exports = {
trailingSlash: true,
}
export pages as index.html files and require trailing slashes, /about becomes /about/index.html and is routable via /about/. This was the default behavior prior to Next.js 9.
现在您可以将 Link
定义保留为:
<Link href="/Pricing">
<a>Pricing</a>
</Link>
这导致 Next.js 做两件事:
- 使用url
example.com/Pricing/
- 注意最后的/
- 在其自己的目录中将每个页面生成为
index.html
- 例如/Pricing/index.html
许多 HTML 服务器在其默认配置中,如果在 URL 中看到尾随 /
字符,将从匹配目录中提供 index.html
.
S3 也会这样做,如果您将其设置为网站并且 IFF 您可以通过
因此您的 Cloudfront 分发来源必须配置为 Origin type = Custom Origin
指向类似 example.com.s3-website.us-east-1.amazonaws.com
的域, 而不是 作为 S3 Origin
.
如果您有 Cloudfront/S3 mis-configured,当您点击“尾部斜杠”样式时 URL - 您可能会看到浏览器下载类型为 [=24= 的文件] 包含 0 bytes
.
编辑:根据issue 16617.
,注意包含.
个字符的页面