如何解决我的 Astro 项目中的以下问题:
我可以从 GraphQL 端点请求各个页面的页面内容
data
。我为此使用Apollo Client。
以以下查询为例:
query Page($target: String!) {
page(target: $target) {
id
type
content {
...on PageOne {
id
title
field
}
...on PageTwo {
id
title
anotherField
}
...on PageThree {
id
title
description
}
}
}
}
In Astro I created dynamic routes:
// pages/[...url].astro
---
import { Page } from '../components/page';
const url = `/${Astro.params.url}`;
---
<Page url={url} />
注意:我喜欢有一个单独的 Astro 组件用于逻辑和映射:
// Page.astro
---
const { url } = Astro.props;
const { data, loading } = await client.query({
query: GET_PAGE,
variables: {
target: url,
},
errorPolicy: 'all',
});
const Map = {
"PageOne": PageOneComponent,
"PageTwo": PageTwoComponent,
};
const Component = Map[data.page?.type]
---
<Component content={content} />
这一切都很好。当点击某个
target
url(存在于后端)时,我可以请求 data
并通过 prop 将其传递给各个相应的 Astro 组件(PageOneComponent、PageTwoComponent 等)。
尝试不存在的页面时就会出现问题。或者尝试使用后端存在的页面类型的页面,但我还没有查询内容,因为我正在逐渐构建和添加页面。
在不存在的页面上
data.page?.type
是 undefined
。我该如何以干净的方式处理这个问题?
我可以在
[...url].astro
中做这样的事情:
if (data.page?.type in Map === false) {
return new Response(null, {
status: 404,
statusText: 'Not found',
});
}
不幸的是,我无法在
Page.astro
内执行上述操作,然后我收到以下错误:
ResponseSentError:响应已发送到浏览器 并且无法更改。
[...url].astro
中进行另一个 GraphQL 查询才能解决这个问题?我可以简单地将所有内容移动到
[...url].astro
,但随后该文件会变得非常拥挤。我喜欢将东西提取到自己的组件和文件夹中。
似乎有两种处理此问题的方法:
Astro.redirect('/404')
或类似按钮将用户重定向到您的 404 页面。从好的方面来说,用户可以获得您在 404 页面中构建的任何外观和功能。缺点是 URL 会切换,因此他们看不到 404 是什么 URL。
无论哪种情况,最好从 GraphQL
error
状态触发此操作,而不是查看 data
对象内部。