简体   繁体   English

Next.js 构建失败,因为“slug”未作为字符串提供

[英]Next.js build fail because "slug" was not provided as string

I'm trying to create a blog using Next.js and typescript, I'm having a problem with [slug].tsx, I keep getting the following error:我正在尝试使用 Next.js 和 typescript 创建博客,我遇到了 [slug].tsx 问题,我不断收到以下错误:

Build error occurred Error: A required parameter (slug) was not provided as a string in getStaticPaths for /blog/[slug]发生构建错误错误:未在 getStaticPaths 中为 /blog/[slug] 提供所需参数(slug)作为字符串

I mainly following this tutorial, this is the exact timestamp:我主要遵循本教程,这是确切的时间戳:
https://youtu.be/jJF6oBw1lbo?t=582 https://youtu.be/jJF6oBw1lbo?t=582

I was successful in following the tutorial in Typescript instead of javascript until I got to this part, now I can't perform the build.我成功地遵循了 Typescript 而不是 javascript 中的教程,直到我到达这一部分,现在我无法执行构建。

When I try to run "yarn run dev", I get this error:当我尝试运行“yarn run dev”时,出现以下错误:

TypeError: Cannot read property 'tap' of undefined TypeError:无法读取未定义的属性“点击”

This is my code for [slug].tsx:这是我的 [slug].tsx 代码:

import { GetStaticPaths, GetStaticProps } from 'next'

let client = require('contentful').createClient({
    space: process.env.CONTENTFUL_SPACE_ID,
    accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,
})

type Params = {
    params: {
        slug: string
    }
}

export const getStaticPaths: GetStaticPaths = async () => {
    let data = await client.getEntries({
        content_type: 'article',
    });
    return {
        paths: data.items.map(item => ({
            params: {slug: item.fields.slug},
        })),
        fallback: true,
    }
}

export const getStaticProps: GetStaticProps = async ({ params }) => {
    let data = await client.getEntries({
        content_type: 'article',
        'fields.slug': params.slug
    })
    return {
        props: {
            article: data.items[0]
        }
    }
}

export default function Article({ article }) {

    return <article>
        <h1>{article.fields.title}</h1>
        {article.fields.content}
    </article>

}

Does the problem have to do with the slug data type?问题是否与 slug 数据类型有关? should I explicitly declare it as a string?我应该明确地将其声明为字符串吗? and how do I do it?我该怎么做?

NextJS getStaticPaths expects that each property on the params object will be a string. NextJS getStaticPaths期望params object 上的每个属性都是一个字符串。 You can see where NextJS throws this error in the source code .您可以在源代码中查看 NextJS 在何处引发此错误。

You've also got that slug type correctly defined (but unused?) here:您还在这里正确定义了slug类型(但未使用?):

type Params = {
    params: {
        slug: string
    }
}

In the getStaticPaths return statement, you're mapping over data from Contentful:getStaticPaths return 语句中,您正在映射来自 Contentful 的数据:

params: {slug: item.fields.slug},

So you'll firstly need to ensure you are returning a string for that params.slug property.因此,您首先需要确保为该params.slug属性返回一个字符串。 This field should have validation and be required as a string in your Contentful content model.此字段应具有验证功能,并且需要作为内容内容 model 中的string

You will also want to defend against that item.fields.slug returning undefined .您还需要防御item.fields.slug返回undefined In my experience, this can happen in Contentful when drafts are auto-saved with empty required fields.根据我的经验,当草稿自动保存为空的必填字段时,这可能会在 Contentful 中发生。

Optional chaining to defensively short-circuit the expression if any reference in the chain is invalid sometimes is useful ie item?.fields?.slug but that's probably not needed here, so try a simple OR logical operator.如果链中的任何引用无效, 可选的链接以防御性地短路表达式有时是有用的,即item?.fields?.slug但这里可能不需要,所以尝试一个简单的 OR 逻辑运算符。

This can probably be written more succinctly but something like this should work in the body of your getStaticPaths function:这可能可以写得更简洁,但这样的东西应该在你的getStaticPaths function 的主体中工作:

const paths = data.items.reduce((pagePaths, item) => {
  const slug = item.fields.slug || '';

  if (slug.length > 0) {
    pagePaths.push({
      params: { slug },
    });
  }

  return pagePaths;
}, []);

return {
  paths,
  fallback: false,
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM