How to Add Confetti Button Explosions to Next.js & React

Ever wondered why apps like Duolingo, Slack, and countless SaaS products use confetti animations? It's not just for fun—confetti creates memorable micro-interactions that boost user engagement and celebrate key moments in your user's journey.
In this tutorial, I'll show you how to implement button-triggered confetti explosions in your Next.js or React app. This technique is perfect for "Buy Now" buttons, form submissions, or any action worth celebrating. The implementation is lightweight, customizable, and production-ready.
By the end of this guide, you'll have working code you can drop into your project today.
Why Add Confetti to Your App?
Confetti animations aren't just decorative—they serve real UX purposes:
- Celebration Micro-Interactions: Reward users when they complete important actions (purchases, signups, achievements)
- Increased Engagement: Fun animations create memorable experiences that users want to share
- Brand Personality: Adds playfulness and humanizes your product
- Visual Feedback: Instantly communicates success without requiring users to read text
Real-world example? Our directory platform ConfettiSaaS uses confetti animations to reinforce our brand identity and create memorable user experiences. Users remember us because of it.
Prerequisites
Before we dive in, make sure you have:
- A Next.js 13+ or React 18+ project set up
- Basic understanding of React hooks (
useState,useEffect) - Node.js and npm/yarn installed
That's it! The library we'll use handles all the complex animation logic for you.
Button-Triggered Confetti Explosion
This implementation is perfect for action buttons like "Buy Now," "Submit," or "Complete Task." When users click, confetti explodes from the button before navigating to the next page.
Install the Package
First, install the react-dom-confetti library:
npm install react-dom-confetti
# or
yarn add react-dom-confettiCreate the BuyButton Component
Create a new file components/BuyButton.tsx (or .jsx for JavaScript projects).
Step 1: Set up imports and component structure
'use client'
import { useRouter } from 'next/navigation';
import React from 'react';
import Confetti from 'react-dom-confetti';
const BuyButton = ({ url }: { url: string }) => {
const router = useRouter();
const [isExploding, setIsExploding] = React.useState(false);The 'use client' directive is required in Next.js 13+ for client-side interactivity. We track the confetti state with isExploding.
Step 2: Add the click handler logic
const handleBuyClick = () => {
setIsExploding(true);
setTimeout(() => {
setIsExploding(false);
router.push(url);
}, 600);
};When clicked, we trigger the confetti, wait 600ms for the animation, then navigate to the target URL.
Step 3: Create the button with confetti
return (
<div className="mb-4 mx-auto justify-end">
<button
onClick={handleBuyClick}
className="w-full font-bold max-w-lg mx-auto py-4 bg-green-500 text-white p-2 text-xl rounded-md shadow-lg hover:bg-green-600 transition duration-300 block"
>
Buy Now!
<div className="flex justify-center items-center">
<Confetti
active={isExploding}
config={{
angle: 90,
spread: 360,
startVelocity: 40,
elementCount: 70,
dragFriction: 0.12,
duration: 3000,
stagger: 3,
width: "10px",
height: "10px",
colors: ["#a864fd", "#22c1c3", "#ffce42", "#ff4081", "#32cd32", "#ff4500", "#1e90ff", "#ff69b4"],
}}
/>
</div>
</button>
</div>
);
};
export default BuyButton;How It Works
Let's break down the key parts:
- 'use client' Directive: Required in Next.js 13+ App Router since we're using client-side interactivity
- State Management:
isExplodingtracks whether confetti should be active - Click Handler: Sets confetti to active, waits 600ms, then navigates to the URL
- Confetti Component: Takes an
activeprop and aconfigobject
Understanding the Configuration
The config object gives you fine control over the confetti behavior:
- angle: Direction of confetti (90 = upward, 180 = downward)
- spread: How wide the confetti disperses (360 = full circle)
- startVelocity: Initial speed of confetti pieces (higher = faster)
- elementCount: Number of confetti pieces (more = denser)
- dragFriction: How quickly confetti slows down (0.1 = slower fall)
- duration: How long confetti stays visible (milliseconds)
- stagger: Delay between each piece launching
- width/height: Size of individual confetti pieces
- colors: Array of hex colors for confetti pieces
Using the Component
Import and use your new confetti button anywhere in your app:
import BuyButton from '@/components/BuyButton';
export default function PricingPage() {
return (
<div>
<h1>Premium Plan</h1>
<p>$99/month</p>
<BuyButton url="/checkout" />
</div>
);
}That's it! When users click "Buy Now," they'll see a celebratory confetti explosion before being redirected.
Customization Ideas
Match Your Brand Colors:
colors: ["#your-brand-primary", "#your-brand-secondary", "#accent-color"]Subtle Animation (Professional Apps):
elementCount: 30,
startVelocity: 20,
colors: ["#e0e0e0", "#c0c0c0", "#a0a0a0"]Intense Celebration (Gaming/Social):
elementCount: 150,
startVelocity: 60,
duration: 5000Common Use Cases
Success Page After Signup
Here's a practical example: one-time confetti burst on a success page.
'use client'
import { useEffect, useState } from 'react';
import Confetti from 'react-dom-confetti';
export default function SuccessPage() {
const [showConfetti, setShowConfetti] = useState(false);
useEffect(() => {
// Trigger confetti on mount
setShowConfetti(true);
// Reset after animation
const timer = setTimeout(() => setShowConfetti(false), 3000);
return () => clearTimeout(timer);
}, []);
return (
<div className="flex flex-col items-center justify-center min-h-screen">
<h1>Welcome aboard! 🎉</h1>
<p>Your account has been created successfully.</p>
<div className="flex justify-center">
<Confetti
active={showConfetti}
config={{
angle: 90,
spread: 360,
startVelocity: 40,
elementCount: 100,
dragFriction: 0.12,
duration: 3000,
stagger: 3,
width: "10px",
height: "10px",
colors: ["#a864fd", "#22c1c3", "#ffce42", "#ff4081"],
}}
/>
</div>
</div>
);
}Achievement Unlock
Trigger confetti when users unlock achievements:
<button
onClick={() => {
setIsExploding(true);
unlockAchievement('first-purchase');
}}
className="achievement-button"
>
Claim Reward
<Confetti active={isExploding} config={achievementConfig} />
</button>Combine the visual celebration with your backend logic for immediate user feedback.
Troubleshooting Common Issues
Hydration Errors in Next.js
Problem: "Hydration failed because the initial UI does not match what was rendered on the server."
Solution: Always use 'use client' directive at the top of your component file.
Confetti Not Appearing
Problem: Confetti renders but isn't visible.
Solutions:
- Check z-index: Ensure confetti isn't hidden behind other elements
- Verify state: Console.log your
isExplodingstate to confirm it's changing - Check for CSS conflicts: Some CSS resets might affect the confetti container
// Debug state changes
const handleBuyClick = () => {
console.log('Triggering confetti');
setIsExploding(true);
setTimeout(() => {
setIsExploding(false);
router.push(url);
}, 600);
};Button Confetti Positioning Issues
Problem: Confetti appears in wrong location.
Solution: Ensure the confetti div is positioned correctly relative to the button:
<button style={{ position: 'relative' }}>
<div style={{ position: 'absolute', left: '50%', top: '50%' }}>
<Confetti active={isExploding} config={config} />
</div>
</button>Timing Adjustments
Quick Success Feedback:
setTimeout(() => {
router.push(url);
}, 400); // Faster navigationDramatic Celebration:
setTimeout(() => {
router.push(url);
}, 2000); // Let confetti play longerWhat's Next?
You now have a production-ready button confetti implementation that adds delight to user interactions. This technique works perfectly for:
- Call-to-action buttons
- Form submissions
- Achievement unlocks
- Purchase confirmations
Want more confetti effects? Stay tuned for more tutorials on adding continuous background confetti to your entire app—perfect for landing pages and branded experiences like we use on ConfettiSaaS.com.
Resources
- react-dom-confetti: npm package
- Original gist: Button confetti implementation
Ready to make your app more fun? Drop this implementation into your project today and watch user engagement improve. And if you're building a SaaS product, don't forget to list it on ConfettiSaaS for visibility and backlinks!
Have questions about implementing button confetti? Found a creative use case? Let's chat on Twitter or in the comments below.


