If youโre building a web app with Next.js in 2025, youโve probably come across this cryptic warning: “Warning: Only plain objects can be passed to Client Components from Server Components.” It sounds scary, right? Donโt worryโitโs a common issue, and itโs totally fixable! This guide will break down what this warning means, why it happens, and how to resolve it in a way thatโs easy to understand, even if youโre new to Next.js.
Table of Contents
What Does the “Only Plain Objects” Warning Mean?
The warning pops up in Next.js when youโre trying to pass data from a Server Component to a Client Component, but the data isnโt in the right format. Specifically, Next.js expects plain JavaScript objects (like { name: "John", age: 30 }), but youโve passed something more complexโlike a function, a class instance, or a Date object.
Why Does This Happen?
Next.js uses a powerful feature called the App Router (introduced in Next.js 13 and still rocking in 2025) to split your app into Server Components and Client Components. Hereโs the deal:
- Server Components run on the server, fetch data, and render HTML. Theyโre super fast because they donโt ship JavaScript to the browser.
- Client Components run in the browser and handle interactive stuff, like button clicks or form inputs. They need to be โhydratedโ with JavaScript.
When a Server Component passes data to a Client Component (via props), Next.js serializes the data into JSON. JSON only supports plain objects, arrays, strings, numbers, booleans, and null. If you try to pass something like a function or a complex object, Next.js throws the warning because it canโt serialize it properly.
A Quick Example
Imagine you have a Server Component that fetches user data and passes it to a Client Component:
// Server Component (page.js)
async function Page() {
const user = {
name: "John",
createdAt: new Date(), // Uh-oh! Date object
sayHello: () => "Hello!" // Uh-oh! Function
};
return <ClientComponent user={user} />;
}
// Client Component (ClientComponent.js)
'use client';
export default function ClientComponent({ user }) {
return <div>{user.name}</div>;
}
Here, new Date() and sayHello arenโt plain objects. When Next.js tries to serialize user to pass it to the Client Component, it freaks out and shows the warning.
Why Should You Care About This Warning?
You might think, โItโs just a warning, not an errorโcanโt I ignore it?โ Well, not really. Hereโs why this matters:
- Broken Features: Non-serializable data (like functions) might not work in the Client Component, causing bugs.
- Performance Issues: Complex objects can slow down your app or cause hydration errors.
- Bad User Experience: If the Client Component doesnโt render correctly, your users might see glitches.
- SEO Impact: Errors in rendering can hurt your siteโs search engine rankings, especially if Google canโt crawl your pages properly.
Fixing this warning makes your app faster, more reliable, and SEO-friendlyโwin-win!
Common Causes of the “Only Plain Objects” Warning
Letโs look at the most common reasons this warning shows up in Next.js apps:
- Passing Date Objects
JavaScriptDateobjects arenโt JSON-serializable. For example,{ createdAt: new Date() }will trigger the warning. - Passing Functions or Methods
Functions, like() => console.log("Hi"), canโt be serialized because JSON doesnโt support executable code. - Passing Class Instances
If you pass an instance of a class (likenew User()), itโs not a plain object and will cause the warning. - Passing Complex Data Structures
Things likeMap,Set, or custom objects with circular references canโt be serialized easily. - Third-Party Library Issues
Some libraries return complex objects (e.g., MongoDBโsObjectIdor Prismaโs model instances) that arenโt plain objects.
How to Fix the “Only Plain Objects” Warning
Now that you know why the warning happens, letโs fix it! Here are step-by-step solutions for the most common scenarios, complete with code examples.
Solution 1: Convert Non-Serializable Data to Plain Objects
The easiest fix is to transform your data into a plain object before passing it to the Client Component. Hereโs how:
Example: Fixing a Date Object
// Server Component (page.js)
async function Page() {
const user = {
name: "John",
createdAt: new Date().toISOString(), // Convert Date to string
};
return <ClientComponent user={user} />;
}
// Client Component (ClientComponent.js)
'use client';
export default function ClientComponent({ user }) {
return <div>{user.name} joined on {user.createdAt}</div>;
}
By converting new Date() to a string with toISOString(), the data becomes JSON-serializable, and the warning disappears.
Example: Removing Functions
// Server Component (page.js)
async function Page() {
const user = {
name: "John",
// No functions here!
};
return <ClientComponent user={user} />;
}
If the Client Component needs logic, move the function to the Client Component itself:
// Client Component (ClientComponent.js)
'use client';
export default function ClientComponent({ user }) {
const sayHello = () => "Hello!";
return <div>{user.name} says {sayHello()}</div>;
}
Solution 2: Handle Complex Objects from APIs or Databases
If youโre fetching data from an API or database (like MongoDB or Prisma), the returned objects might include non-serializable fields. You need to โcleanโ the data first.
Example: Cleaning MongoDB Data
MongoDBโs ObjectId and Date fields often cause issues. Hereโs how to fix it:
// Server Component (page.js)
import { MongoClient } from 'mongodb';
async function Page() {
const client = await MongoClient.connect('mongodb://localhost:27017');
const db = client.db('mydb');
const rawUser = await db.collection('users').findOne({ name: "John" });
// Convert to plain object
const user = {
name: rawUser.name,
createdAt: rawUser.createdAt.toISOString(), // Convert Date
id: rawUser._id.toString(), // Convert ObjectId to string
};
return <ClientComponent user={user} />;
}
For Prisma, you can use JSON.parse(JSON.stringify(data)) as a quick fix, but be carefulโitโs not always the most efficient:
// Server Component (page.js)
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function Page() {
const rawUser = await prisma.user.findFirst();
const user = JSON.parse(JSON.stringify(rawUser)); // Converts to plain object
return <ClientComponent user={user} />;
}
Solution 3: Move Logic to Client Components
If your Server Component is trying to pass functions or complex logic, consider moving that logic to the Client Component. Server Components are meant for fetching data and rendering static content, while Client Components handle interactivity.
Example: Moving Event Handlers
// Server Component (page.js)
async function Page() {
const user = { name: "John" };
return <ClientComponent user={user} />;
}
// Client Component (ClientComponent.js)
'use client';
export default function ClientComponent({ user }) {
const handleClick = () => alert(`Hi, ${user.name}!`);
return <button onClick={handleClick}>Say Hi</button>;
}
Solution 4: Use use Hook for Client-Side Data Fetching
If you need complex data in a Client Component, you can fetch it directly in the Client Component using the use hook (available in Next.js 13+). This avoids passing non-serializable data altogether.
// Server Component (page.js)
async function Page() {
return <ClientComponent />;
}
// Client Component (ClientComponent.js)
'use client';
import { use } from 'react';
async function fetchUser() {
const res = await fetch('/api/user');
return res.json();
}
export default function ClientComponent() {
const user = use(fetchUser());
return <div>{user.name}</div>;
}
Solution 5: Use a Serialization Library
For advanced cases, you can use libraries like superjson to handle complex data types. superjson serializes things like Date, Map, and Set into a format that Next.js can handle.
Example: Using superjson
// Server Component (page.js)
import superjson from 'superjson';
async function Page() {
const user = {
name: "John",
createdAt: new Date(),
};
const serializedUser = superjson.stringify(user);
return <ClientComponent serializedUser={serializedUser} />;
}
// Client Component (ClientComponent.js)
'use client';
import superjson from 'superjson';
export default function ClientComponent({ serializedUser }) {
const user = superjson.parse(serializedUser);
return <div>{user.name} joined on {user.createdAt.toString()}</div>;
}
Note: Install superjson with npm install superjson and ensure itโs compatible with your Next.js version.
Best Practices to Avoid the Warning
To keep your Next.js app warning-free, follow these best practices:
- Always Use Plain Objects for Props
Before passing props from a Server Component, double-check that theyโre plain objects or arrays. Use tools likeJSON.stringify()to test serializability. - Keep Server Components Lean
Server Components should focus on fetching data and rendering static content. Move interactivity (like event handlers) to Client Components. - Clean API/Database Data
Always transform API or database responses into plain objects before passing them to Client Components. - Use TypeScript for Safety
TypeScript can help catch non-serializable props at compile time. Define interfaces for your props to ensure theyโre plain objects. - Test Hydration
After fixing the warning, test your app to ensure Client Components hydrate correctly. Use Next.jsโs dev mode (npm run dev) to spot issues.
Debugging the Warning
If youโre still seeing the warning, hereโs how to track down the culprit:
- Check the Stack Trace
The warning usually includes a stack trace in your terminal or browser console. Look for the file and line number where the prop is being passed. - Log the Props
Addconsole.log(props)in your Client Component to inspect whatโs being passed. Look for non-serializable types like functions or Dates. - Simplify the Data
Temporarily simplify the props being passed (e.g.,{ name: "Test" }) to isolate the issue. - Use Next.js Dev Tools
Next.jsโs development mode highlights hydration errors and warnings. Runnpm run devand check the console.
SEO Benefits of Fixing This Warning
Fixing the โOnly plain objectsโ warning isnโt just about clean codeโitโs also great for SEO! Hereโs why:
- Faster Page Loads: Properly serialized props mean smoother hydration, which improves your siteโs Core Web Vitals (like LCP and FCP).
- Better Crawling: Googlebot loves error-free pages. Fixing this warning ensures your pages render correctly for search engines.
- Improved User Experience: A bug-free app keeps users on your site longer, reducing bounce rates and boosting rankings.
To maximize SEO, also:
- Use descriptive
<title>and<meta>tags with your focus keyword (โNext.js only plain objects warningโ). - Add internal links to related pages (e.g., a guide on Next.js Server Components).
- Optimize images with
next/imagefor faster load times.
FAQs About the “Only Plain Objects” Warning
What is a plain object in JavaScript?
A plain object is a simple key-value structure, like { name: "John", age: 30 }. It doesnโt include functions, Dates, or complex types like Map or Set.
Can I ignore this warning?
Not recommended! It can cause hydration errors, broken features, or performance issues in your Next.js app.
Does this warning only happen in Next.js?
Yes, itโs specific to Next.jsโs App Router, which splits components into Server and Client Components and requires JSON-serializable props.
How do I know if my props are serializable?
Test them with JSON.stringify(props). If it throws an error, your props arenโt serializable.
Conclusion: Master Next.js with Confidence
The โOnly plain objects can be passed to Client Components from Server Componentsโ warning might seem intimidating, but itโs a sign that youโre diving into the exciting world of Next.jsโs App Router! By understanding why this warning happens and following the solutions above, you can build faster, more reliable, and SEO-friendly web apps in 2025.
Whether youโre converting Dates to strings, cleaning database data, or moving logic to Client Components, these fixes will make your Next.js apps shine. So, go aheadโsquash that warning, test your app, and keep exploring the awesome possibilities of Next.js!
Resources
- Stack Overflow: Only Plain Objects Warning โ Community answers to this warning.
- Next.js Documentation โ Official guide to Server and Client Components.
- Vercel Blog โ Stay updated on Next.js best practices.