Error: Failed to collect page data for /api/products/[slug]

Question

Hi. Can you please help me to solve the problem? I have this file and locally everything works fine.

// /app/(public)/catalog/page.tsx
'use client'

import { useEffect, useState } from 'react'
import Link from 'next/link'

type Product = {
  id: number
  name: string
  slug: string
  imageUrl: string
  description: string
  price: number
  benefit: number
}

const CatalogPage = () => {
  const [products, setProducts] = useState<Product[]>([])
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    const fetchProducts = async () => {
      const response = await fetch('/api/products', { cache: 'no-store' })
      const data = await response.json()
      setProducts(data)
      setLoading(false)
    }
    fetchProducts()
  }, [])

  if (loading) {
    return (
      <div className="p-4">
        <h1 className="text-3xl font-bold mb-4">Catalog</h1>
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
          {[...Array(6)].map((_, index) => (
            <div
              key={index}
              className="border p-4 rounded-lg shadow-md animate-pulse">
              <div className="bg-gray-300 h-6 w-3/4 mb-2"></div>
              <div className="bg-gray-300 h-48 w-full mb-2"></div>
              <div className="bg-gray-300 h-4 w-full mb-2"></div>
              <div className="bg-gray-300 h-4 w-1/2 mb-2"></div>
            </div>
          ))}
        </div>
      </div>
    )
  }

  if (products.length === 0) {
    return <div className="p-4">No products available yet.</div>
  }

  return (
    <div className="p-4">
      <h1 className="text-3xl font-bold mb-4">Catalog</h1>
      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
        {products.map((product) => (
          <div
            key={product.id}
            className="border p-4 rounded-lg shadow-md">
            <Link
              className="text-xl font-semibold"
              href={`/catalog/${product.slug}`}>
              {product.name}
            </Link>
            <img
              src={product.imageUrl}
              alt={product.name}
              className="mt-2 w-full h-48 object-cover rounded"
            />
            <p className="mt-2">{product.description}</p>
            <p className="mt-2">Price: {product.price}</p>
            <p className="mt-2">Benefit: {product.benefit}</p>
          </div>
        ))}
      </div>
    </div>
  )
}

export default CatalogPage

But when I upload it to Vercel I get an error. I have specified all keys, I feel that I need to add domain before api, but I tried different variants, but the server domain transfer does not work in the client.

// /app/(public)/catalog/page.tsx
'use client';

import { useEffect, useState } from 'react';
import Link from 'next/link';

type Product = {
  id: number;
  name: string;
  slug: string;
  imageUrl: string;
  description: string;
  price: number;
  benefit: number;
};

const CatalogPage = ({ apiUrl }) => {
  const [products, setProducts] = useState<Product[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const fetchProducts = async () => {
      const response = await fetch(`${apiUrl}/api/products`);
      const data = await response.json();
      setProducts(data);
      setLoading(false);
    };
    fetchProducts();
  }, [apiUrl]);

  if (loading) {
    return (
      <div className="p-4">
        <h1 className="text-3xl font-bold mb-4">Catalog</h1>
        <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
          {[...Array(6)].map((_, index) => (
            <div
              key={index}
              className="border p-4 rounded-lg shadow-md animate-pulse">
              <div className="bg-gray-300 h-6 w-3/4 mb-2"></div>
              <div className="bg-gray-300 h-48 w-full mb-2"></div>
              <div className="bg-gray-300 h-4 w-full mb-2"></div>
              <div className="bg-gray-300 h-4 w-1/2 mb-2"></div>
            </div>
          ))}
        </div>
      </div>
    );
  }

  if (products.length === 0) {
    return <div className="p-4">No products available yet.</div>;
  }

  return (
    <div className="p-4">
      <h1 className="text-3xl font-bold mb-4">Catalog</h1>
      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
        {products.map((product) => (
          <div
            key={product.id}
            className="border p-4 rounded-lg shadow-md">
            <Link
              className="text-xl font-semibold"
              href={`/catalog/${product.slug}`}>
              {product.name}
            </Link>
            <img
              src={product.imageUrl}
              alt={product.name}
              className="mt-2 w-full h-48 object-cover rounded"
            />
            <p className="mt-2">{product.description}</p>
            <p className="mt-2">Price: {product.price}</p>
            <p className="mt-2">Benefit: {product.benefit}</p>
          </div>
        ))}
      </div>
    </div>
  );
};

export async function getServerSideProps() {
  return {
    props: {
      apiUrl: process.env.NEXTAUTH_URL,
    },
  };
}

export default CatalogPage;```

I use prisma + postgresql from vergel

<img width="1261" alt="Снимок экрана 2024-07-16 в 19 54 52" src="https://github.com/user-attachments/assets/8ac0ed8f-598b-46f8-90bc-9b0b6335deee">

Hi @thefubon.

If the first code example is working on local, then I wouldn’t expect that you need to prefix an apiUrl when deployed. Is /api/products part of your app, or is it part of a separate API?

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.