简体   繁体   中英

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:

Build error occurred Error: A required parameter (slug) was not provided as a string in getStaticPaths for /blog/[slug]

I mainly following this tutorial, this is the exact timestamp:
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.

When I try to run "yarn run dev", I get this error:

TypeError: Cannot read property 'tap' of undefined

This is my code for [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? 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. You can see where NextJS throws this error in the source code .

You've also got that slug type correctly defined (but unused?) here:

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

In the getStaticPaths return statement, you're mapping over data from Contentful:

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

So you'll firstly need to ensure you are returning a string for that params.slug property. This field should have validation and be required as a string in your Contentful content model.

You will also want to defend against that item.fields.slug returning undefined . In my experience, this can happen in Contentful when drafts are auto-saved with empty required fields.

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.

This can probably be written more succinctly but something like this should work in the body of your 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,
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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