DEV Community

Cover image for How to build the ChatGPT typing animation in React
Stiaan Wolfaardt
Stiaan Wolfaardt

Posted on

How to build the ChatGPT typing animation in React

ChatGPT utilizes a typing animation that emulates the appearance of typing on old-fashioned computer screens.

This animation is achieved through two important concepts:

  1. The text is displayed one character at a time, creating the illusion of typing.
  2. A flashing cursor indicates the location of the character currently being typed.

Let's start by examining how to display the text one character at a time:

useEffect(() => {
  setCompletedTyping(false);

  let i = 0;
  const stringResponse = chatHistory[chatHistory.length - 1].content

  const intervalId = setInterval(() => {
    setDisplayResponse(stringResponse.slice(0, i));

    i++;

    if (i > stringResponse.length) {
      clearInterval(intervalId);
      setCompletedTyping(true);
    }
  }, 20);

  return () => clearInterval(intervalId);
}, [chatHistory]);
Enter fullscreen mode Exit fullscreen mode

To display the text character by character, use a simple setInterval function that sets a state variable at each interval. This state variable is then displayed to the user. The setInterval function continues calling the specified function until clearInterval is called. In our case, we call clearInterval when we have finished typing the entire string.

The source of the string that will be displayed to the user depends on your app. We use a useEffect hook that triggers each time ChatGPT sends a new response to a prompt. We store each response in an array of objects called chatHistory. To display only the last response in the array, we use chatHistory[chatHistory.length - 1].content. This retrieves the last object in the array.

I set the intervals to 20 milliseconds, but you can adjust this to fit your app.

Now, let's move on to creating the flashing cursor. We use an SVG and CSS keyframes to achieve this effect:

This is achieved using a SVG and CSS keyframes.

The SVG we used for this purpose is the following:

<svg
  viewBox="8 4 8 16"
  xmlns="http://www.w3.org/2000/svg"
  className="cursor"
>
  <rect x="10" y="6" width="4" height="12" fill="#fff" />
</svg>
Enter fullscreen mode Exit fullscreen mode

Notice the cursor className. Here's what it looks like:

.cursor {
  display: inline-block;
  width: 1ch;
  animation: flicker 0.5s infinite;
  margin-bottom: 4px;
}
Enter fullscreen mode Exit fullscreen mode

This will add the flicker animation to the SVG and ensure that it is properly aligned with the text being typed, appearing inline with it.

The flicker animation referenced here is as follows:

@keyframes flicker {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}
Enter fullscreen mode Exit fullscreen mode

You then have to include the SVG in your JSX. This will ensure that the SVG is only visible when typing is in progress and has not yet been completed.

<span>
  {displayResponse}
  {!completedTyping && <CursorSVG />}
</span>
Enter fullscreen mode Exit fullscreen mode

With these steps in place, you'll be able to achieve the iconic ChatGPT typing animation!

If you'd like to view the source code I used to achieve this effect, you can follow this link to my GitHub repository:
https://github.com/STIAANWOL/therapistgpt

If you'd like to see this effect in action with a live demo, you can follow this link:
https://therapistgpt-stiaanwol.vercel.app/

I hope this has been helpful to you, and happy coding!

Top comments (3)

Collapse
 
nguyenbathanh profile image
Thanh Nguyen

Works great. Thank you!

Collapse
 
shakirshakeel profile image
Shakir Shakeel

Check out my blog explaing why ChatGPT does this medium.com/@shakirshakeel/understa...

Collapse
 
nightwalker89 profile image
CQ

I think we should calculate the amount of interval to adjust the speed based on the length of text chunk