I’m using the App router of nextjs 13, with typescript, and I’m trying to create dynamic pages and generate the paths for them with generateStaticParams().
The function generateStaticParams() seems to work, and it collects the correct information. But when I want to use the information in my component, I get a undefined value.
The page is fetchting the data correctly if I hardcode the ID, so I only need to swap this for the ID collected with the generateStaticParams.
How can I make sure that the page is receiving the data from generateStaticParams?
/src/app/coffeeplaces/[coffeeplace]/page.tsx
import fetchCoffeePlace from "@/api/fetchCoffeeplace";
import { db } from "@/helpers/firebaseConfig";
import { collection, getDocs } from "firebase/firestore";
import Image from "next/image";
import { Suspense } from "react";
import ImagesCarousel from "./components/imagesCarousel";
import Link from "next/link";
import CoffeeMainDetails from "./components/coffeeMainDetails";
export default async function Page({ params }: { params: { id: string, slug: string } }) {
const { id, slug } = params
// this comes back UNDEFINED
console.log('id', params.id) // or id
console.log('slug', params.slug) // or slug
// This hardcoded option works to fetch the data
// const id = 'r7CFv3t4Ni5sNl20wE8h'
const CoffeeplaceData = fetchCoffeePlace(id);
const CoffeeplaceInfoData = fetchCoffeePlace(id); //
const coffeeplace = await CoffeeplaceData;
return (
<div>
<Link href={'/coffeeplaces'} className="text-sm font-light">Back to listing</Link>
<Suspense fallback={<div>Loading...</div>}>
<CoffeeplaceInfo promise={CoffeeplaceInfoData} />
</Suspense>
</div>
);
}
async function CoffeeplaceInfo({ promise, }: { promise: Promise<CoffeePlace>; }) {
const coffeeplaceInfo = await promise;
return (
<>
<div className="pt-6 lg:flex w-full">
<ImagesCarousel featuredImage={coffeeplaceInfo.featuredImage} />
<CoffeeMainDetails name={coffeeplaceInfo.name} priceRange={coffeeplaceInfo.priceRange} organic={coffeeplaceInfo.organic} fairTrade={coffeeplaceInfo.fairTrade}/>
</div>
</>
)
}
export async function generateStaticParams() { // tried with this: generateStaticParams({ params: { id, slug }}: any)
const coffeePlaces = await getDocs(collection(db, "coffeePlaces"));
const data = coffeePlaces.docs.map((doc) => ({
id: doc.id,
...doc.data()
}));
var slugify = require('slugify')
const result = data.map((item) => {
const slug = slugify(item.name, {
replacement: '-',
lower: true,
strict: true,
});
// these are logging the correct values
console.log(item.id);
console.log(slug);
return {
params: {
id: item.id,
slug: slug
}
};
});
// this is logging the correct result
// [{ params: { id: '9ZVOCYsngTksBKXqQQOH', slug: 'coffeeplace-1' } }, { params: { id: 'r7CFv3t4Ni5sNl20wE8h', slug: 'example-2' } } ]
return result;
}
Small other thing, might be related, in the generateStaticParams function, when I loop over the result, for the item.name it says: Property 'name' does not exist on type '{ id: string; }')
2
Answers
Bart.
I am glad to answer your question.
In my humble opinion, there’s some errors to fix.
This is my code snippets that corrected yours.
First part.
Second part.
I wonder this would be okay but please try it once.
your
result
array has this formatwhen you reach
params
inPage
component, you should be using,because
params
in each dynamic page is