Chatbot
Shimmer
An animated text shimmer component for creating eye-catching loading states and progressive reveal effects.
The Shimmer component provides an animated shimmer effect that sweeps across text, perfect for indicating loading states, progressive reveals, or drawing attention to dynamic content in AI applications.
This text has a shimmer effect
Large Heading
Slower shimmer with wider spread
"use client";import { Shimmer } from "@/components/ai-elements/elements/shimmer";const Example = () => ( <div className="flex flex-col items-center justify-center gap-4 p-8"> <Shimmer>This text has a shimmer effect</Shimmer> <Shimmer as="h1" className="font-bold text-4xl"> Large Heading </Shimmer> <Shimmer duration={3} spread={3}> Slower shimmer with wider spread </Shimmer> </div>);export default Example;Installation
npx ai-elements@latest add shimmernpx shadcn@latest add @ai-elements/shimmer"use client";import { cn } from "@repo/shadcn-ui/lib/utils";import { motion } from "motion/react";import { type CSSProperties, type ElementType, type JSX, memo, useMemo,} from "react";export type TextShimmerProps = { children: string; as?: ElementType; className?: string; duration?: number; spread?: number;};const ShimmerComponent = ({ children, as: Component = "p", className, duration = 2, spread = 2,}: TextShimmerProps) => { const MotionComponent = motion.create( Component as keyof JSX.IntrinsicElements ); const dynamicSpread = useMemo( () => (children?.length ?? 0) * spread, [children, spread] ); return ( <MotionComponent animate={{ backgroundPosition: "0% center" }} className={cn( "relative inline-block bg-[length:250%_100%,auto] bg-clip-text text-transparent", "[--bg:linear-gradient(90deg,#0000_calc(50%-var(--spread)),var(--color-background),#0000_calc(50%+var(--spread)))] [background-repeat:no-repeat,padding-box]", className )} initial={{ backgroundPosition: "100% center" }} style={ { "--spread": `${dynamicSpread}px`, backgroundImage: "var(--bg), linear-gradient(var(--color-muted-foreground), var(--color-muted-foreground))", } as CSSProperties } transition={{ repeat: Number.POSITIVE_INFINITY, duration, ease: "linear", }} > {children} </MotionComponent> );};export const Shimmer = memo(ShimmerComponent);Usage
import { Shimmer } from '@/components/ai-elements/shimmer';<Shimmer>Loading your response...</Shimmer>Features
- Smooth animated shimmer effect using CSS gradients and Framer Motion
- Customizable animation duration and spread
- Polymorphic component - render as any HTML element via the
asprop - Automatic spread calculation based on text length
- Theme-aware styling using CSS custom properties
- Infinite looping animation with linear easing
- TypeScript support with proper type definitions
- Memoized for optimal performance
- Responsive and accessible design
- Uses
text-transparentwith background-clip for crisp text rendering
Examples
Different Durations
Fast (1 second)
Loading quickly...
Default (2 seconds)
Loading at normal speed...
Slow (4 seconds)
Loading slowly...
Very Slow (6 seconds)
Loading very slowly...
"use client";import { Shimmer } from "@/components/ai-elements/elements/shimmer";const Example = () => ( <div className="flex flex-col gap-6 p-8"> <div className="text-center"> <p className="mb-3 text-muted-foreground text-sm">Fast (1 second)</p> <Shimmer duration={1}>Loading quickly...</Shimmer> </div> <div className="text-center"> <p className="mb-3 text-muted-foreground text-sm">Default (2 seconds)</p> <Shimmer duration={2}>Loading at normal speed...</Shimmer> </div> <div className="text-center"> <p className="mb-3 text-muted-foreground text-sm">Slow (4 seconds)</p> <Shimmer duration={4}>Loading slowly...</Shimmer> </div> <div className="text-center"> <p className="mb-3 text-muted-foreground text-sm"> Very Slow (6 seconds) </p> <Shimmer duration={6}>Loading very slowly...</Shimmer> </div> </div>);export default Example;Custom Elements
As paragraph (default)
This is rendered as a paragraph
As heading
Large Heading with Shimmer
As span (inline)
Processing your request with AI magic...
As div with custom styling
Custom styled shimmer text
"use client";import { Shimmer } from "@/components/ai-elements/elements/shimmer";const Example = () => ( <div className="flex flex-col gap-6 p-8"> <div className="text-center"> <p className="mb-3 text-muted-foreground text-sm"> As paragraph (default) </p> <Shimmer as="p">This is rendered as a paragraph</Shimmer> </div> <div className="text-center"> <p className="mb-3 text-muted-foreground text-sm">As heading</p> <Shimmer as="h2" className="font-bold text-2xl"> Large Heading with Shimmer </Shimmer> </div> <div className="text-center"> <p className="mb-3 text-muted-foreground text-sm">As span (inline)</p> <div> Processing your request{" "} <Shimmer as="span" className="inline"> with AI magic </Shimmer> ... </div> </div> <div className="text-center"> <p className="mb-3 text-muted-foreground text-sm"> As div with custom styling </p> <Shimmer as="div" className="font-semibold text-lg"> Custom styled shimmer text </Shimmer> </div> </div>);export default Example;Props
<Shimmer />
Prop
Type