Next.js SSG 捕获所有路由的正确 .htaccess 设置

Proper .htaccess settings for Next.js SSG catch all routes

我建立了一个网站,使用 Next.js 和 SSG - 静态网站生成。 我在 Apache 服务器上为网站提供服务,因此,由于 ,我使用以下 .htaccess 配置:

# Disable directory indexes and MultiViews
Options -Indexes -MultiViews

# Prevent mod_dir appending a slash to directory requests
DirectorySlash Off

# Rewrite /foo to /foo.html if it exists
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.html -f
RewriteRule !\.\w{2,4}$ %{REQUEST_URI}.html [L]

# Otherwise, rewrite /foo to /foo/index.html if it exists
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}/index.html -f
RewriteRule !\.\w{2,4}$ %{REQUEST_URI}/index.html [L]

# Handling 404
ErrorDocument 404 /my-custom-404.html

它一直运行良好。

但最近需要一个管理页面,通常是 CRUD。我在没有考虑 SSG 的情况下开发它(因为实际上不需要它),创建了我自己的自定义路由器并使用 Next.js's catch all routes 来处理这个管理页面的所有内容,我称之为 dashboard .

因此,在我构建的网站上,我有一大堆 page.html 文件和一个 /dashboard/[[...dashboard]].html 文件,即 CRUD 本身(所有子页面和内容都是动态导入的)- 和,因此,每个以 /dashboard 开头的 link 都将通过该文件处理。

所以,问题是: 通过网站上的 link 导航并进入 仪表板 ,一切正常完美。但是,如果我尝试 直接 访问 /dashboard 中的任何 link (包括自身和子路由:例如 /dashboard/users),它根本不会工作。使用提供的 .htaccess 配置,它直接进入 404.

我尝试了一些添加到 .htaccess 的不同配置,但是 none 到目前为止都有效(它仍然直接进入 404,或者浏览器显示错误 ERR_TOO_MANY_REDIRECTS):

RewriteCond %{DOCUMENT_ROOT}/dashboard/
RewriteRule (.*) /dashboard/[[...dashboard]].html [L]

这个几乎可以工作...但是仪表板本身不执行任何操作(从未呈现任何子页面):

RewriteCond %{REQUEST_URI} .*dashboard*.
RewriteRule (.*) /dashboard/[[...dashboard]].html [L]

重要说明:这一切在本地开发服务器上运行完美。

如果有人能告诉我如何解决这个问题,我将不胜感激!

我已经设法解决了,至少在可接受的水平上。

正如我在问题中提到的,这几乎可以正常工作(没有呈现任何子页面,但至少浏览器正确重定向到仪表板):

RewriteCond %{REQUEST_URI} .*dashboard*.
RewriteRule (.*) /dashboard/[[...dashboard]].html [L]

没有页面被渲染,因为我使用 Next.js 的 withRouter/useRouter 来通知我的自定义路由器当前路由(通过 router.asPath),并且当上述规则正如遇见的那样,router.asPath 被设置为 dashboard/[[...dashboard]].html。 因此,我编写了一个小测试来将使用该 asPath 的任何访问重定向到我的入口点。基本上:

if(router.asPath.contains('[[...dashboard]]')
    router.push('/dashboard')

但是,另一个问题引起了... 第一个问题已解决:尝试直接访问任何仪表板路由都可以,但无法浏览网站(链接)。经过艰苦而漫长的反复试验后,我发现我之前的 .htaccess 规则阻止我的客户端代码请求我的 [[...dashboard]].html 文件。

RewriteCond %{REQUEST_URI} .*dashboard*.
RewriteCond %{REQUEST_URI} !(\[\[\.\.\.dashboard\]\])
RewriteRule (.*) /dashboard/[[...dashboard]].html?p= [L]

基本上:

  • 如果我的请求 URI 包含 'dashboard'
  • 并且如果同一请求不包含 [[...dashboard]]
  • 然后我将其重写到仪表板文件

希望有一天这对某人有所帮助!