SSG 页面的 NextJS 不区分大小写的路由

时间:2021-06-24 13:07:09

标签: next.js url-routing

我正在使用 NextJS 将数据的 CSV 转换为静态页面。每页都是pages/[slug].jsx。我正在对 [slug].jsx toLowerCase()getStaticPaths() 函数中的 slug 值调用 getStaticProps()。生成的页面是小写的。例如/ab101、/ab102、/cc500 都解析为 pages/[slug].jsx 页面。

不幸的是,人们可能会手动输入网址,并且可能对 slug 值使用大写或大小写混合,目前导致 404。

问题:如何使路由对 slug 值不区分大小写?

更新

当我从 fallback: true 返回 getStaticPaths() 时,即使没有完全匹配的路径,我的 [slug].jsx 文件也会被命中。然后我可以检查 isFallback,如下面的 Anish Antony 所示。

此外,当找不到页面时,传递给我的页面的 items 参数将是未定义的。路由器的 pathname 值是 "/[slug]" 而不是“slug”的值。但是,有一个 asPath 值包含有用的数据,例如/mixedCaseSlug?param=value&foo=bar

当页面呈现时,我检查它是否是后备。如果是,则显示 LOADING... 消息。接下来将显示该内容并调用 getStaticProps() 以生成“缺失”页面。然后,您将使用页面数据重新呈现。如果 getStaticProps 无法获取页面数据,我会推送一条路径,该路径将通向内置 404 页面。

export default function Page({ item }) {
  const { isFallback, push } = useRouter()
  const hasPageData = item && Object.keys(item).length > 0
  useEffect(() => {
    if (!isFallback && !hasPageData) {
      push('/page-not-found/error')
    }
  }, [isFallback, hasPageData])
  const loadingMsg = <div>Loading...</div>
  const notFoundMsg = <div>Page not found</div>
  return isFallback ? loadingMsg : hasPageData ? <Item item={item} /> : notFoundMsg
}

我需要更新 getStaticProps() 以小写 slug 参数,因为它现在可能是大小写混合的,但我们想要找到我们的页面数据。我需要考虑到实际上没有 slug 数据的情况。

export async function getStaticProps({ params }) {
  const { slug } = params
  const item = data.find(o => o.Practice_Code.trim().toLowerCase() === slug.toLowerCase())
  return {
    props: {
      item: item ? item : {}
    }
  }
}

这一切看起来都很笨拙,所以我仍然想知道是否有更好的方法。

1 个答案:

答案 0 :(得分:0)

NextJS 路由区分大小写。您可以使用 getStaticPaths 中的回退属性来捕获与 getStaticPaths 中默认提供的路由不同的路由。

编辑:我根据与 Dave 的讨论更新了答案。

我们可以提供 fallback:true 或 fallback:"blocking" ,如果我们提供 fallback:true 我们可以显示一个自定义组件,该组件将一直显示到加载时间页面为止。对于 fallback:"blocking" 不返回新路径通过 getStaticPaths 将等待 HTML 生成,

当我们提供 fallback:true 或“阻止”静态页面时,将在用户第一次访问网站时生成静态页面,生成的页面将用于进一步访问。

示例代码

export async function getStaticPaths() {
  const idList = await fetchAllIds();
  const paths = [
  ];
  idList.forEach((id) => {paths.push(`/posts/${id}`)})
  return { paths, fallback: true };
}

我们注意到我们在 getStaticProps 中的代码应该不区分大小写以获取数据,而不管 url 中提供的数据如何。


export async function getStaticProps({ params }) {
  const { slug } = params;

 try {
    /// This fetch api should be able to fetch the data irrespective of the case of the slug 
or we should convert it to the required case before passing it as a parameter to API
    const data= await fetchSlugDetails(slug);
//Same logic should be performed if you are getting data filtered based on slug from an existing array.
    return data? { props: { data} } : { notFound: true };
  } catch (error) {
    console.error(error);
    return { notFound: true };
  }

}


注意:如果您使用 fallback:true,则必须处理 notfound 情况和 fallback 情况。对于回退,您可以在静态生成页面时从 next/router 获取值 isFallback