OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

revalidate doesn't seem to work with generateStaticParams in nextJS 14

  • Thread starter Thread starter Rom-888
  • Start date Start date
R

Rom-888

Guest
I have a headless nextjs app with strapi on next 14 with the app router. I'm using output:export to statically export my app on ngnix server. I had some problems to generate the static files for the dynamic routes. I solved it by using a client component to fetch the product data, so I separated the logic into 2 files :

page.tsx :

Code:
import { getStrapiData } from "app/api/api"
import ProductPage from "."

// Generate static parameters
export const revalidate = 60
export async function generateStaticParams() {
  try {
    // Fetch product data from the API
    const { data: products } = await getStrapiData("/api/products")
    // Map product IDs to static paths
    return products.map((product) => ({
      slug: product.slug,
    }))
  } catch (error) {
    console.error("Error fetching product IDs:", error)
    return [] // Return an empty array in case of an error
  }
}

// Multiple versions of this page will be statically generated
// using the `params` returned by `generateStaticParams`
export default function ServerPage({ params }: { params: { slug: string } }) {
  return <ProductPage params={{ slug: params.slug }} />
}

index.tsx :

Code:
"use client"

import { getProductBySlug } from "app/api/api"
import { useEffect, useState } from "react"
import { ProductData } from "types/types"
import Product from "@/components/Product/product"
import ProductDetails from "@/components/Product/productDetails"
import { pathBottom, pathTop } from "@/components/SVG/Stroke"

interface Props {
  params: {
    slug: string
  }
}
export default function ProductPage({ params }: Props) {
  const { slug } = params
  console.log("Generating page for product slug:", slug)

  const [product, setProduct] = useState<ProductData | null>(null)

  useEffect(() => {
    async function fetchData() {
      try {
        const response = await getProductBySlug(slug)
        const productData = response.data[0] // Accès au premier élément du tableau data
        console.log("Product fetched:", productData)
        setProduct(productData)
      } catch (error) {
        console.error("Error fetching product data:", error)
      }
    }
    fetchData()
  }, [slug])

  if (!product) {
    return <div className="mx-auto mt-32 w-screen text-center text-xl text-blue">Chargement...</div> // Handle loading state if needed
  }

  const { game_bonux } = product
  const color = game_bonux?.color

  if (!color) {
    console.error("Le produit ou sa propriété color est indéfini.")
    return <div>Error: Product data incomplete.</div> // Handle error state
  }

  const svgTop = (
    <svg
      width="100%"
      height="28"
      viewBox="0 0 720 28"
      preserveAspectRatio="none"
      fill={color}
      xmlns="http://www.w3.org/2000/svg"
    >
      {pathTop}
      fill={color}
    </svg>
  )

  const svgBottom = (
    <svg
      width="100%"
      height="28"
      viewBox="0 0 720 28"
      preserveAspectRatio="none"
      fill={color}
      xmlns="http://www.w3.org/2000/svg"
    >
      {pathBottom}
      fill={color}
    </svg>
  )

  return (
    <>
      {/* Section Hero */}
      <div className="mt-16 hidden md:block">{svgTop}</div>
      <Product product={product} color={color} />
      <div className="-mt-1 hidden md:block">{svgBottom}</div>
      <ProductDetails product={product} />
    </>
  )
}

It worked but when I add a product in the back office, the params don't seem to be revalidated, or at least the new routes is leading to a 404 error

<p>I have a headless nextjs app with strapi on next 14 with the app router. I'm using output:export to statically export my app on ngnix server. I had some problems to generate the static files for the dynamic routes. I solved it by using a client component to fetch the product data, so I separated the logic into 2 files :</p>
<p>page.tsx :</p>
<pre><code>import { getStrapiData } from "app/api/api"
import ProductPage from "."

// Generate static parameters
export const revalidate = 60
export async function generateStaticParams() {
try {
// Fetch product data from the API
const { data: products } = await getStrapiData("/api/products")
// Map product IDs to static paths
return products.map((product) => ({
slug: product.slug,
}))
} catch (error) {
console.error("Error fetching product IDs:", error)
return [] // Return an empty array in case of an error
}
}

// Multiple versions of this page will be statically generated
// using the `params` returned by `generateStaticParams`
export default function ServerPage({ params }: { params: { slug: string } }) {
return <ProductPage params={{ slug: params.slug }} />
}
</code></pre>
<p>index.tsx :</p>
<pre><code>"use client"

import { getProductBySlug } from "app/api/api"
import { useEffect, useState } from "react"
import { ProductData } from "types/types"
import Product from "@/components/Product/product"
import ProductDetails from "@/components/Product/productDetails"
import { pathBottom, pathTop } from "@/components/SVG/Stroke"

interface Props {
params: {
slug: string
}
}
export default function ProductPage({ params }: Props) {
const { slug } = params
console.log("Generating page for product slug:", slug)

const [product, setProduct] = useState<ProductData | null>(null)

useEffect(() => {
async function fetchData() {
try {
const response = await getProductBySlug(slug)
const productData = response.data[0] // Accès au premier élément du tableau data
console.log("Product fetched:", productData)
setProduct(productData)
} catch (error) {
console.error("Error fetching product data:", error)
}
}
fetchData()
}, [slug])

if (!product) {
return <div className="mx-auto mt-32 w-screen text-center text-xl text-blue">Chargement...</div> // Handle loading state if needed
}

const { game_bonux } = product
const color = game_bonux?.color

if (!color) {
console.error("Le produit ou sa propriété color est indéfini.")
return <div>Error: Product data incomplete.</div> // Handle error state
}

const svgTop = (
<svg
width="100%"
height="28"
viewBox="0 0 720 28"
preserveAspectRatio="none"
fill={color}
xmlns="http://www.w3.org/2000/svg"
>
{pathTop}
fill={color}
</svg>
)

const svgBottom = (
<svg
width="100%"
height="28"
viewBox="0 0 720 28"
preserveAspectRatio="none"
fill={color}
xmlns="http://www.w3.org/2000/svg"
>
{pathBottom}
fill={color}
</svg>
)

return (
<>
{/* Section Hero */}
<div className="mt-16 hidden md:block">{svgTop}</div>
<Product product={product} color={color} />
<div className="-mt-1 hidden md:block">{svgBottom}</div>
<ProductDetails product={product} />
</>
)
}
</code></pre>
<p>It worked but when I add a product in the back office, the params don't seem to be revalidated, or at least the new routes is leading to a 404 error</p>
 
Top