Browse components
Typing Animation
A minimal typing animation with smart backspacing, an optional cursor, and adjustable speed.
Add to your project
Pick the way you like to build.
Let your AI assistant add it
Copy this prompt and paste it into the AI tool building your site.
# Integrate this UI component
Add this component to my project.
1. Install any missing dependencies.
2. Make sure Tailwind CSS is set up and scans the new file.
3. Prefer passing props over editing the component source — changing the component itself may break it.
4. Adjust colors, size, and layout via props or wrapper classes to match my project. You know my codebase better than this snippet does.
## Component source
```tsx
"use client";
import { useEffect, useRef, useState } from "react";
type TypingAnimationProps = {
children?: string;
speed?: number;
deleteSpeed?: number;
cursor?: boolean;
className?: string;
};
export default function TypingAnimation({
children = "Make something great.",
speed = 65,
deleteSpeed = 30,
cursor = true,
className = "",
}: TypingAnimationProps) {
const [displayed, setDisplayed] = useState("");
const current = useRef<string[]>([]);
useEffect(() => {
const target = Array.from(
new Intl.Segmenter(undefined, { granularity: "grapheme" }).segment(children),
({ segment }) => segment,
);
const preference = window.matchMedia("(prefers-reduced-motion: reduce)");
let timer: ReturnType<typeof setTimeout>;
function advance() {
clearTimeout(timer);
if (preference.matches) {
current.current = target;
setDisplayed(children);
return;
}
const value = current.current;
const matches = value.every((letter, index) => letter === target[index]);
if (matches && value.length === target.length) return;
timer = setTimeout(() => {
current.current = matches
? target.slice(0, value.length + 1)
: value.slice(0, -1);
setDisplayed(current.current.join(""));
advance();
}, Math.max(0, matches ? speed : deleteSpeed));
}
advance();
preference.addEventListener("change", advance);
return () => {
clearTimeout(timer);
preference.removeEventListener("change", advance);
};
}, [children, speed, deleteSpeed]);
return (
<span className={`whitespace-pre-wrap ${className}`}>
<span className="sr-only">{children}</span>
<span aria-hidden="true" className="motion-reduce:hidden">
{displayed}
{cursor && (
<span className="ml-0.5 inline-block h-[0.9em] w-[2px] animate-pulse bg-current align-baseline" />
)}
</span>
<span aria-hidden="true" className="hidden motion-reduce:inline">{children}</span>
</span>
);
}
```
Works with your AI tools
* Compatible with most projects that use the default React/Next.js framework.
Built With
Props
| Prop | Type | Description |
|---|---|---|
children | string | Text to type. Changing it backspaces only the differing suffix. |
speed | number | Milliseconds per typed character. Default: 65. |
deleteSpeed | number | Milliseconds per deleted character. Default: 30. |
cursor | boolean | Show the cursor. Default: true. |
className | string | Customize typography, color, and layout. |