Astro 项目中如何处理动态路由、不存在的页面以及 GraphQL 请求中不存在的数据

问题描述 投票:0回答:1

如何解决我的 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:响应已发送到浏览器 并且无法更改。

  1. 我是否必须在
    [...url].astro
    中进行另一个 GraphQL 查询才能解决这个问题?
  2. 另一种情况(现有页面没有内容)又如何?
  3. 只是一个不存在的页面,应该返回 404 页面。

我可以简单地将所有内容移动到

[...url].astro
,但随后该文件会变得非常拥挤。我喜欢将东西提取到自己的组件和文件夹中。

javascript graphql http-status-code-404 astrojs
1个回答
0
投票

似乎有两种处理此问题的方法:

    使用
  1. Astro.redirect('/404') 或类似按钮将用户
    重定向
    到您的 404 页面。从好的方面来说,用户可以获得您在 404 页面中构建的任何外观和功能。缺点是 URL 会切换,因此他们看不到 404 是什么 URL。
  2. 渲染一个未找到组件。

无论哪种情况,最好从 GraphQL

error
状态触发此操作,而不是查看
data
对象内部。

© www.soinside.com 2019 - 2024. All rights reserved.