我已经创建了一个盖茨比应用程序,并将gatsby-node.js
配置为仅创建客户端的路径,这些路径在开发中都可以正常工作,而直接访问路径的url却不在生产环境中。
示例:
if(page.path.match(/^\/sample/)){
page.matchPath = "/sample/:value1/:value2/:value3";
createPage(page)
}
我正在使用heroku
来部署应用程序
答案 0 :(得分:7)
原因
尽管客户端路由器知道此路径,但没有相应的HTML文件。当浏览器查看该站点时,它首先加载由gatsby生成的404.html
文件,其中包括客户端路由器。路由器完成初始化后,将读取路径并加载正确的页面。意味着您最终到达了正确的位置,但是到达错误页面的时间只有半秒钟。
如何修复
一般的解决方案是告诉服务器将/sample/
路径重定向到您的/sample/index.html
文件。进行此操作的方式取决于您的主机,但是我将为各种主机提供该技术的名称,以防您需要查找它。通常称为URL重写,每个主要的托管平台都应支持它。
Heroku
gatsby deploy documentation的Heroku部分建议使用heroku-buildpack-static模块,该模块内置了对“自定义路线”的支持,它将使用以下语法为您的情况解决此问题:
{
"routes": {
"/sample/**": "sample/index.html",
}
}
答案 1 :(得分:3)
这解决了我的问题
pages/404.jsx
import React, { useEffect, useState } from 'react';
export default ()=>{
const [isMount, setMount] = useState(false);
useEffect(() => {
setMount(true);
},[])
if(!isMount) {
return(
<div>loading</div>
)
}
return (
<div>Page Not Found</div>
)
}
在响应为 404 之前,这不会在客户端呈现上显示 404 错误。
答案 2 :(得分:1)
对于使用S3(gatsby-plugin-s3)和CloudFront的任何人,我已通过在gatsby-plugin-s3配置中添加generateMatchPathRewrites: false
并为原始请求创建Lambd @ Edge函数来解决302/404问题使用以下代码:
exports.handler = async (event) => {
const request = event.Records[0].cf.request;
if (/^\/app\//i.test(request.uri)) {
request.uri = '/app/index.html';
}
return request;
};
尽管302/404消失了,但是在进行强制刷新时仍然遇到问题。例如,当我在/ app / page2并单击刷新时,/ app中的默认组件将加载,然后半秒后,/ app / page2中的组件将显示,但方式很奇怪。 / app的某些CSS类混在/ app / page2中。如果有人对此有任何想法,请告诉我。
答案 3 :(得分:0)
我在公用文件夹中查找了我创建的客户路由的索引文件
对于netlify,我在根目录的netlify.toml文件中添加了以下内容。
[[redirects]]
from = "/user/dashboard/"
to = "/user/index.html"
status = 200
答案 4 :(得分:0)
对于Firebase托管,我在firebase.json
中添加了以下内容:
"rewrites": [
{
"source": "**",
"destination": "/loading/index.html"
}
]
然后我在loading.js
下创建了一个新的/page
文件。使用此配置,Firebase首先使用loading.html
进行响应,然后Gatsby处理客户端路由。
答案 5 :(得分:0)
heroku 解决方案对我不起作用,但我不知道确切原因。我的前端正在从 express.js 后端获取数据。我通过在我的 server.js
中添加以下几行来重定向我的客户只路由来解决我的问题。
app.get('/user/**', (req, res) => {
res.sendFile(path.join(`${__dirname}/public/user/index.html`));
});
答案 6 :(得分:0)
对于希望在 Vercel 平台上解决此问题的任何人,答案是重写:https://vercel.com/docs/configuration#project/rewrites
如果您有一个只有客户端路径的 gatsby 应用程序,例如 https://www.gatsbyjs.com/plugins/gatsby-plugin-create-client-paths/,您很可能会在部署时遇到这个问题。
示例:您的应用程序的路径类似于 mything.com/app/user-profile。
在这种情况下,app/* 是客户端专用的路由,不会在服务器上生成,因此当您重新加载此路由或登陆该路由时,您可能会收到 404 的闪现例如,直接来自外部链接。
要解决,请在 Vercel 中的 /app/* 服务器端路由上添加重写以指向 /app,假设您的路由受到控制通过 Reach 路由器或您的 pages/app.js 文件中的类似文件。
要在 Vercel 上进行设置,请在 gatsby/react 项目的根目录中创建 vercel.json 并添加以下配置:
{
"rewrites": [{ "source": "/app/:match*", "destination": "/app" }]
}
此问题通常仅在部署到生产/暂存时才会出现。它不会在开发中发生(无论如何通过 gatsby develop)。
答案 7 :(得分:0)
对于本地开发,您必须使用神奇的 [...].js
文件名。
您可以在此处查看演示存储库:https://github.com/gatsbyjs/gatsby/tree/master/examples/client-only-paths/src/pages
答案 8 :(得分:0)
NGINX
如果您的环境包含 Nginx,您应该在您的虚拟主机配置中添加如下内容:
rewrite ^/products/([0-9]*)$ /products/[id]/index.html;
或
rewrite ^/users/confirm/(.*)$ /users/confirm/[code]/index.html;
等
只需转到您的生产根目录并为您的案例查找 index.html 文件的正确路径。
通常您的虚拟主机配置位于:/etc/nginx/sites-enabled/mysite.com.conf