When you first start building applications in React, you learn to pass data into components using props. This works beautifully for text or numbers. But what happens when you want to pass an entire chunk of user interface, like a specific button, an icon, or a custom heading, inside another component?
If you try to control all of that with basic text strings and true/false switches, your code quickly becomes messy and hard to read.
This is exactly where the Slot Pattern comes to the rescue.
The Mental Model
Instead of hardcoding exactly what goes inside a component, think of your component as a structural layout with labeled, empty boxes. We call these boxes slots.
The component doesn't care what goes inside those boxes; its only job is to arrange them nicely on the screen using CSS. The developer using the component gets to decide exactly what content to slide into those slots.
The Problem: Prop Nightmare
Imagine a component that keeps growing because different pages need different variations:
const OldCard = ({ title, showButton, buttonText }) => {
return (
<div className="card-box">
<div className="card-header">
<h2>{title}</h2>
</div>
<div className="card-body">
<p>Main content lives here...</p>
</div>
{showButton && <button>{buttonText}</button>}
</div>
);
};
Hard to maintain this code. What if a page wants an icon next to the title? You have to add a new prop!
The Solution: The Named Slot Pattern
Instead of passing strings, let's tell our component to accept a React Node (which means any valid JSX or HTML code) directly through the props!
// Clean & Flexible: The component just sets up the layout slots
export const CleanCard = ({ headerSlot, footerSlot }) => {
return (
<div className="card-box">
{/* Here is the header slot */}
<div className="card-header">{headerSlot}</div>
<div className="card-body">
<p>Main content lives here...</p>
</div>
{/* Here is the footer slot */}
<div className="card-footer">{footerSlot}</div>
</div>
);
};
Now, look at how flexible this is when you actually use it on a webpage. You can pass simple text, custom styled buttons, or even images straight into those slot props:
import { CleanCard } from "./CleanCard";
const Dashboard = () => {
return (
<CleanCard
headerSlot={
<div className="flex gap-2">
🔥 <h3>Featured Article</h3>
</div>
}
footerSlot={<button className="btn-primary">Read More</button>}
/>
);
};
Ready to Master More Component Layouts?
Now that you understand the basic concept of named placeholders, you're ready to see how this scales into advanced application design patterns.
Watch the complete, visual code-along lesson on Day 12: React Slot Pattern Explained in our 15 Days of React Design Patterns series on YouTube.




