I'm using Strapi as a CMS, where I query for slugs, and I would like to have statically generated pages using getStaticPaths and getStaticProps in Next.js.
As I need to work with multiple locales, I have to map through the locales and get paths for each "Announcements" I'm getting from my query.
The error message I'm getting is:
Error: A required parameter (slug) was not provided as a string in getStaticPaths for /updates/announcements/[slug]
This is my getStaticPaths:
export async function getStaticPaths({ locales }: any) {
const paths = await (
await Promise.all(
locales.map(async (locale: any) => {
const { data } = await client.query({
query: gql`
query Announcements {
announcements(locale: "${locale}") {
data {
attributes {
slug
locale
}
}
}
}
`,
});
return {
announcements: data.announcements.data,
locale,
};
})
)
).reduce((acc, item) => {
item.announcements.map((p: any) => {
acc.push({
params: {
slug:
p.attributes.slug === "/" ? false : p.attributes.slug.split("/"),
},
locale: p.attributes.locale,
});
return p;
});
return acc;
}, []);
return {
paths,
fallback: false,
};
}
If I console.log(paths) I get the following in the terminal:
[
{ params: { slug: [Array] }, locale: 'en' },
{ params: { slug: [Array] }, locale: 'en' },
{ params: { slug: [Array] }, locale: 'en' },
{ params: { slug: [Array] }, locale: 'da' },
{ params: { slug: [Array] }, locale: 'sv' },
{ params: { slug: [Array] }, locale: 'nb' }
]
I might think that Next.js don't want the slug to be an array, but I'm not entirely sure. What am I doing wrong?
You page uses dynamic routes named (/updates/announcements/[slug]
), therefore the param slug
is required in paths
.
From the Next.js getStaticPaths
documentation:
The
paths
key determines which paths will be pre-rendered. For example, suppose that you have a page that uses Dynamic Routes namedpages/posts/[id].js
. If you exportgetStaticPaths
from this page and return the following forpaths
:return { paths: [ { params: { id: '1' }}, { params: { id: '2' }, // with i18n configured the locale for the path can be returned as well locale: "en", }, ], fallback: ... }
Then, Next.js will statically generate
/posts/1
and/posts/2
duringnext build
using the page component inpages/posts/[id].js
.
The slug
param can only be a string
since it's used to generate routes. As you found when logging paths
, you were trying to pass slug: [Array]
.
The problem in the question's code snippet is this expression to assign a slug
:
// ...
params: {
slug: p.attributes.slug === "/" ? false : p.attributes.slug.split("/"), // 👈
},
// ...
This expression will either assign false
(boolean) or an array of substrings (see the docs for String.prototype.split()
).
In this case, as confirmed in a comment above, simply passing the slug as a string solves the issue.
The confusion likely came from following a tutorial that uses an optional catch-all route (pages/[[...slug]]
) instead of regular dynamic routes (pages/[slug]
) (ref).
From the Next.js getStaticPaths
documentation again:
- If the page name is
pages/posts/[postId]/[commentId]
, then params should containpostId
andcommentId
.- If the page name uses catch-all routes like
pages/[...slug]
, then params should containslug
(which is an array). If this array is['hello', 'world']
, then Next.js will statically generate the page at/hello/world
.- If the page uses an optional catch-all route, use
null
,[]
,undefined
orfalse
to render the root-most route. For example, if you supplyslug: false
forpages/[[...slug]]
, Next.js will statically generate the page/
.