Next.js+MongoDB项目部署Vercel失败:/products预渲染报错
The error SyntaxError: Unexpected token < in JSON at position 0 means your fetchProducts function is receiving HTML (likely a 404 or error page) instead of JSON during the build process. This happens because getStaticProps runs at build time, and your API routes aren’t accessible yet—either the production URL isn’t live, or you’re hitting a local endpoint that doesn’t exist on Vercel’s build servers.
Solution Steps
1. Query MongoDB Directly in getStaticProps
Skip calling your API endpoint via fetch and access the database directly in getStaticProps. This removes the need for a live API during build time.
Modify products.tsx:
First, import your MongoDB connection utility (adjust the path to match your project):
import { connectToDatabase } from '../../../lib/mongodb';
Update getStaticProps to fetch data directly from MongoDB:
export const getStaticProps: GetStaticProps = async () => { try { const db = await connectToDatabase(); // Fetch products from your MongoDB collection const products = await db.collection('products').find().toArray(); // Convert MongoDB ObjectId to string for safe serialization const formattedProducts = products.map(product => ({ ...product, _id: product._id.toString() })); return { props: { products: formattedProducts } }; } catch (error) { console.error('Error fetching products from database:', error); throw error; } };
2. Adjust fetchProducts for Client-Side Use (If Needed)
If you use fetchProducts on the client side (e.g., for dynamic updates after deployment), keep it as is—but ensure NEXT_PUBLIC_APIURL points to your live Vercel URL once deployed. For server-side/build-time use, replace it with direct database calls.
3. Verify Environment Variables
- Private Credentials: Ensure your MongoDB connection string (e.g.,
MONGODB_URI) is set as a non-NEXT_PUBLIC_environment variable in Vercel.NEXT_PUBLIC_variables are exposed to the client, which is unsafe for database credentials. - Check Values: Confirm Vercel’s environment variables match your local setup (exclude local-only values like
localhost).
4. Optional: Add Revalidation for Dynamic Content
If your product list updates frequently, add revalidate to getStaticProps to regenerate the page periodically without a full rebuild:
return { props: { products: formattedProducts }, revalidate: 60 // Regenerate page every 60 seconds };
Why This Works
By querying MongoDB directly in getStaticProps, you avoid relying on a live API endpoint during the build process. This eliminates the HTML error response that caused the JSON parsing failure.
内容的提问来源于stack exchange,提问作者lucas oliveira

