Examples
Landing Page Animations
Dynamic
Include the initial text in every string, and the static part will only be typed out once.
<TypeAnimation
sequence={[
// Same substring at the start will only be typed once, initially
'We produce food for Mice',
1000,
'We produce food for Hamsters',
1000,
'We produce food for Guinea Pigs',
1000,
'We produce food for Chinchillas',
1000,
]}
speed={50}
style={{ fontSize: '2em' }}
repeat={Infinity}
/>
Note: Typing complex characters like emojis requires a custom splitter function.
Initially Pre-rendered
By using the preRenderFirstString
prop, you can initially (pre-)render the very first string of your sequence. When used with SSR (Next.js or similar), the initial string will be included in the static HTML, which may benefit SEO.
<div>
<TypeAnimation
preRenderFirstString={true}
sequence={[
500,
'We produce food for Mice', // initially rendered starting point
1000,
'We produce food for Hamsters',
1000,
'We produce food for Guinea Pigs',
1000,
'We produce food for Chinchillas',
500,
]}
speed={50}
style={{ fontSize: '2em' }}
repeat={Infinity}
/>
</div>
Continuation
<TypeAnimation
sequence={[
'One',
500,
'One Two', // Continuing previous Text
500,
'One Two Three',
500,
'One Two',
500,
'One',
500,
'',
500,
]}
style={{ fontSize: '2em' }}
repeat={Infinity}
/>
Replacement
<TypeAnimation
sequence={['One', 500, 'Two', 500, 'Three', 500]}
style={{ fontSize: '2em' }}
repeat={Infinity}
/>
Custom Speed
As mentioned in the props section, you can specify both the typing speed
and deletionSpeed
with a simple relative number between 1-99 or an exactly specified keystroke delay.
Note: The animation adds a random delay relative to your
provided speed
and deletionSpeed
after each keystroke to make the typing
animation look more natural.
Multiple Lines
By addding the white-space: pre-line
css style and placing '\n'
anywhere in your text, or making actual line breaks inside a string literal, you can write in multiple lines.
<TypeAnimation
style={{ whiteSpace: 'pre-line', height: '195px', display: 'block' }}
sequence={[
`Line one\nLine Two\nLine Three\nLine Four\nLine Five
Line Seven`, // actual line-break inside string literal also gets animated in new line, but ensure there are no leading spaces
1000,
'',
]}
repeat={Infinity}
/>
Using the explicit \n
new-line is preferred, because your code formatter may
add spaces in new lines of the string literal that will be typed out as an
empty string and hence unintentionally delay the animation.
Pre-define the height and width of the parent element to prevent layout shift when typing multi-lines
Callback Functions
Use callback functions at any place inside of your animation sequence to perform any (global) actions you want. An exemplary use-case for this is calling functions or state updates that manipulate the styles of your animation component, or let your application know at which state of typing the animation currently is, and adjusting some other visual elements accordingly.
const [typingStatus, setTypingStatus] = useState('Initializing');
<TypeAnimation
sequence={[
1500,
() => {
setTypingStatus('Typing...');
},
'Use callback-functions to trigger events',
() => {
setTypingStatus('Done Typing');
},
1000,
() => {
setTypingStatus('Deleting...');
},
'',
() => {
setTypingStatus('Done Deleting');
},
]}
repeat={Infinity}
/>;
Manipulation via CSS Classes
It's possible to manipulate the animation styles in order to, for example, stop the cursor animation at a specific point within the animation sequence:
const CURSOR_CLASS_NAME = 'custom-type-animation-cursor';
return (
<>
<TypeAnimation
cursor={false}
style={{
fontSize: '1.75rem',
}}
className={CURSOR_CLASS_NAME}
sequence={[
'One',
800,
'One Two',
800,
'One Two Three',
(el) => el.classList.remove(CURSOR_CLASS_NAME), // A reference to the element gets passed as the first argument of a callback function
6000,
(el) => el.classList.add(CURSOR_CLASS_NAME),
'',
]}
repeat={Infinity}
/>
<style global jsx>{`
.custom-type-animation-cursor::after {
content: '|';
animation: cursor 1.1s infinite step-start;
}
@keyframes cursor {
50% {
opacity: 0;
}
}
`}</style>
</>
);
Manipulation via State
By applying dynamic styles to the parent element of the TypeAnimation
component, you can easily manipulate styles without classNames and passing ref.
const [textColor, setTextColor] = useState('red');
return (
<>
<div
style={{
fontSize: '35px',
color: textColor,
/* when working without ref and classNames, the manipulated style needs to be
applied to the parent element, because the TypeAnimation component is perma-memoized */
}}
>
<TypeAnimation
sequence={[
'One',
800,
() => setTextColor('aqua'),
'One Two',
800,
() => setTextColor('deeppink'),
'One Two Three',
1000,
() => setTextColor('darkkhaki'),
'',
]}
repeat={Infinity}
/>
</div>
<button
onClick={() => {
const items = [
'blue',
'green',
'purple',
'pink',
'brown',
'darkmagenta',
'darksalmon',
'dodgerblue',
'firebrick',
'darkviolet',
];
setTextColor(items[Math.floor(Math.random() * items.length)]); // set random color
}}
>
Change Color
</button>
</>
);
Custom String Splitter
By default, strings placed inside the sequence
are split character by character, to simulate keyboard-like typing. With he help of the splitter
prop, it's possible to define a custom splitting of sequence strings.
Typing Word by Word
To create a word-level typing animation similar to ChatGPT or other AI chatbots, we can split strings into single words, rather than characters.
<TypeAnimation
splitter={(str) => str.split(/(?= )/)} // 'Lorem ipsum dolor' -> ['Lorem', ' ipsum', ' dolor']
sequence={[
'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.',
3000,
'',
]}
speed={{ type: 'keyStrokeDelayInMs', value: 30 }}
omitDeletionAnimation={true}
style={{ fontSize: '1em', display: 'block', minHeight: '200px' }}
repeat={Infinity}
/>
Typing Complex Characters
As certain complex Unicode characters, like emojis, are internally represented as multiple characters in JavaScript, including them in our animation requires an advanced string splitter, such as grapheme-splitter (opens in a new tab), capable of splitting those characters into extended grapheme clusters (single letters).
import GraphemeSplitter from 'grapheme-splitter'; // npm i grapheme-splitter
const splitter = new GraphemeSplitter();
return (
<TypeAnimation
splitter={(str) => splitter.splitGraphemes(str)}
sequence={[
'Hello 🇬🇧',
2000,
'Ciao 🇮🇹',
2000,
'你好 🇨🇳',
2000,
'Здравейте 🇧🇬 ',
2000,
'Hola 🇪🇸',
2000,
'Bonjour 🇫🇷',
2000,
'नमस्ते 🇮🇳',
2000
]}
style={{ fontSize: '2em' }}
repeat={Infinity}
/>
);