# Text Shimmer

> Animated shimmer effect for text with customizable timing and spread

A shadcn/ui block from the [@elements](https://www.tryelements.dev) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/elements/text-shimmer).

- Page, with a live preview: https://shadcn.exchange/r/elements/text-shimmer
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/elements/text-shimmer-light-dd9d6b959426826d.png
- Registry item: https://www.tryelements.dev/r/text-shimmer.json
- Categories: animations
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://www.tryelements.dev/r/text-shimmer.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- npm packages: `motion`

## Notes from the registry

Polymorphic text component with animated shimmer effect. Supports light/dark mode, customizable duration, spread, delay, and repeatDelay props.

## Files

### `registry/default/blocks/animations/text-shimmer/components/elements/text-shimmer.tsx`

```tsx
"use client";

import React, { type JSX, useMemo } from "react";

import { motion } from "motion/react";

import { cn } from "@/lib/utils";

export type TextShimmerProps = {
  children: string;
  as?: React.ElementType;
  className?: string;
  duration?: number;
  spread?: number;
  delay?: number;
  repeatDelay?: number;
};

function TextShimmerBase({
  children,
  as: Component = "p",
  className,
  duration = 2,
  spread = 2,
  delay = 0,
  repeatDelay = 0,
}: TextShimmerProps) {
  const MotionComponent = motion.create(
    Component as keyof JSX.IntrinsicElements,
  );

  const dynamicSpread = useMemo(() => {
    return children.length * spread;
  }, [children, spread]);

  return (
    <MotionComponent
      data-slot="text-shimmer"
      className={cn(
        "relative inline-block bg-[length:250%_100%,auto] bg-clip-text",
        "text-transparent [--base-color:#a1a1aa] [--base-gradient-color:#000]",
        "[--bg:linear-gradient(90deg,#0000_calc(50%-var(--spread)),var(--base-gradient-color),#0000_calc(50%+var(--spread)))] [background-repeat:no-repeat,padding-box]",
        "dark:[--base-color:#71717a] dark:[--base-gradient-color:#ffffff] dark:[--bg:linear-gradient(90deg,#0000_calc(50%-var(--spread)),var(--base-gradient-color),#0000_calc(50%+var(--spread)))]",
        className,
      )}
      initial={{ backgroundPosition: "105% center" }}
      animate={{ backgroundPosition: "-5% center" }}
      transition={{
        repeat: Number.POSITIVE_INFINITY,
        duration,
        ease: "linear",
        delay,
        repeatDelay,
      }}
      style={
        {
          "--spread": `${dynamicSpread}px`,
          backgroundImage: `var(--bg), linear-gradient(var(--base-color), var(--base-color))`,
        } as React.CSSProperties
      }
    >
      {children}
    </MotionComponent>
  );
}

export const TextShimmer = React.memo(TextShimmerBase);
```

### `registry/default/blocks/animations/text-shimmer/routes/layout.tsx`

```tsx
import { Geist, Geist_Mono } from "next/font/google";

const geistSans = Geist({
  variable: "--font-geist-sans",
  subsets: ["latin"],
});

const geistMono = Geist_Mono({
  variable: "--font-geist-mono",
  subsets: ["latin"],
});

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body
        className={`${geistSans.variable} ${geistMono.variable} antialiased`}
      >
        {children}
      </body>
    </html>
  );
}
```

### `registry/default/blocks/animations/text-shimmer/routes/page.tsx`

```tsx
import { TextShimmer } from "@/registry/default/blocks/animations/text-shimmer/components/elements/text-shimmer";

export default function TextShimmerPage() {
  return (
    <div className="min-h-screen bg-background text-foreground">
      <div className="container mx-auto px-4 py-16">
        <div className="max-w-4xl mx-auto space-y-12">
          <div className="text-center space-y-4">
            <h1 className="text-3xl font-bold">Text Shimmer</h1>
            <p className="text-muted-foreground">
              Animated shimmer effect for text with customizable timing and
              spread.
            </p>
          </div>

          <div className="flex flex-col items-center gap-8">
            <TextShimmer className="text-4xl font-bold" duration={2}>
              Shimmer Effect
            </TextShimmer>
            <TextShimmer className="text-2xl font-medium" duration={1.5}>
              Loading content...
            </TextShimmer>
            <TextShimmer className="text-lg" duration={3} spread={3}>
              Custom spread and duration
            </TextShimmer>
          </div>
        </div>
      </div>
    </div>
  );
}
```
