Back to Dictionary
Empty & Error States
●○○Ready to Use
Recommended default

Connection Error Shake

A more aggressive, persistent pulsing or shaking error state specifically denoting that a system failure or timeout occurred.

Use

Failed API fetches on critical dashboard widgets

Avoid

User-side validation errors (use Error Shake instead)

Safer Alternative

No safer default listed.

Risk Level

Low risk

Live Demo

Connection Failed

We couldn't reach the server. Please check your internet connection or try again later.

What It Is

A more aggressive, persistent pulsing or shaking error state specifically denoting that a system failure or timeout occurred.

When to Use

  • Failed API fetches on critical dashboard widgets
  • Payment gateways failing to connect

When NOT to Use

  • User-side validation errors (use Error Shake instead)

Configuration Tips

  • 01Pair with a "Retry" button that has its own loading spinner state
  • 02Apply a subtle red flash to the container border

You've Seen It In

VercelAWS Console

AI Implementation Prompts

Move from a fast scaffold to production details, then tune timing and edge states.

Create a widget error state that shows a softly pulsing red exclamation icon indicating the data failed to load.

Reference Implementation

The same implementation approach used by the live preview, kept compact enough to inspect and adapt.

"use client";
import { useState, useEffect } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { ServerCrash } from 'lucide-react';

export function ConnectionErrorShakeDemo({ isPlaying = false }: { isPlaying?: boolean }) {
    const [isShaking, setIsShaking] = useState(false);
    const [attempts, setAttempts] = useState(0);

    const handleConnect = () => {
        setAttempts(a => a + 1);
        setIsShaking(true);
        setTimeout(() => setIsShaking(false), 500); "text-stone-400 italic">// 0.5s match animation duration
    };

    useEffect(() => {
        if (!isPlaying) {
            setAttempts(0);
            setIsShaking(false);
            return;
        }
        const interval = setInterval(() => {
            handleConnect();
            setTimeout(() => setAttempts(0), 1000);
        }, 1500);
        return () => clearInterval(interval);
    }, [isPlaying]);

    return (
        <div className="relative flex h-64 w-full flex-col items-center justify-center overflow-hidden rounded-2xl bg-white p-6 shadow-sm ring-1 ring-stone-200">

            <motion.div
                animate={isShaking ? { x: [-10, 10, -8, 8, -5, 5, -2, 2, 0] } : {}}
                transition={{ duration: 0.5 }}
                className="relative flex w-full max-w-xs flex-col items-center overflow-hidden rounded-2xl border border-stone-200 bg-white p-6 text-center shadow-md scale-90"
            >
                <div className="w-16 h-16 bg-red-50 text-red-500 rounded-full flex items-center justify-center mb-6 relative">
                    <ServerCrash className="w-8 h-8" />
                    <AnimatePresence>
                        {attempts > 0 && (
                            <motion.div
                                initial={{ scale: 0 }}
                                animate={{ scale: 1 }}
                                key={attempts}
                                className="absolute -top-1 -right-1 w-6 h-6 bg-red-500 text-white rounded-full flex items-center justify-center text-xs font-bold border-2 border-white"
                            >
                                {attempts}
                            </motion.div>
                        )}
                    </AnimatePresence>
                </div>

                <h3 className="text-xl font-bold text-stone-900 mb-2">Connection Failed</h3>
                <p className="text-stone-500 mb-8 text-sm leading-relaxed">
                    We couldn't reach the server. Please check your internet connection or try again later.
                </p>

                <div className="w-full space-y-3">
                    <button
                        onClick={handleConnect}
                        className="w-full py-3 bg-stone-900 text-white rounded-xl font-medium shadow-sm hover:bg-stone-800 transition-colors focus:ring-4 focus:ring-stone-200 outline-none"
                    >
                        Try Again
                    </button>
                    <button
                        onClick={() => setAttempts(0)}
                        className="w-full py-3 bg-white text-stone-600 border border-stone-200 rounded-xl font-medium hover:bg-stone-50 transition-colors"
                    >
                        Cancel
                    </button>
                </div>

                {"text-stone-400 italic">/* Subtle red flash border on error */}
                <motion.div
                    animate={isShaking ? { opacity: [0, 1, 0] } : { opacity: 0 }}
                    transition={{ duration: 0.5 }}
                    className="absolute inset-0 border-2 border-red-500 rounded-2xl pointer-events-none"
                />
            </motion.div>

        </div>
    );
}