Source Code

Requires
<section class="tjh-hero">
  <div class="tjh-eyebrow">✦ Now hiring</div>
  <h1 class="tjh-heading">We build for<br><span id="tjhTyped" class="tjh-typed"></span><span class="tjh-caret" aria-hidden="true"></span></h1>
  <p class="tjh-sub">One product team, five very different customers — the headline cycles through who we ship for, typed and deleted in a loop by Typed.js.</p>
  <div class="tjh-actions">
    <button class="tjh-btn tjh-primary">See open roles</button>
    <button class="tjh-btn tjh-ghost">Our story →</button>
  </div>
</section>

Typed.js Multi-String Hero — Free Typewriter Headline Snippet

Typed.js Multi-String Hero · Heroes · Plain HTML, CSS & JS · Live preview

What's included

Features

Multi-string cycling
A single strings array drives an unlimited phrase loop.
Independent type/delete speed
typeSpeed and backSpeed tune each direction separately.
Configurable read pause
backDelay controls how long a finished phrase stays visible.
Smart backspacing
smartBackspace avoids re-deleting shared string prefixes.
Custom CSS caret
A separately styled, independently animated blinking cursor.
Gradient typed text
background-clip: text applies a gradient to the cycling phrase.
Looping by default
loop: true keeps the headline cycling indefinitely.
Minimal setup
One constructor call replaces manual interval-based typing logic.

About this UI Snippet

Typed.js Multi-String Hero — Cycling Headlines with a Real Typewriter Loop

Screenshot of the Typed.js Multi-String Hero snippet rendered live

A rotating headline is a common way to communicate that one product serves several different audiences without needing five separate hero sections. This snippet uses Typed.js — a small, purpose-built typewriter animation library — to cycle a hero headline through five phrases, each one typed out, held briefly, and deleted before the next begins, all driven by a single strings array.

One options object, a full animation loop

new Typed('#tjhTyped', { strings: [...], typeSpeed: 48, backSpeed: 28, backDelay: 1400, loop: true }) is the entire animation. Typed.js owns the interval-based logic of adding one character at a time, pausing once a string is fully typed, deleting characters at a different (usually faster) speed, and moving to the next string in the array — looping back to the first once the array is exhausted. Compare this to Typewriter or Split Text, which build a single-string typing effect from scratch; this snippet gets the equivalent behavior across an arbitrary number of strings from one constructor call.

Independent type and delete speeds

typeSpeed: 48 and backSpeed: 28 are deliberately different — text usually reads better typing in a bit slower than it deletes, since deletion is meant to feel like a quick "clearing" gesture rather than a mirrored typing animation. backDelay: 1400 is the pause after a string finishes typing and before deletion starts, giving the reader time to actually read the phrase rather than watching it vanish immediately.

smartBackspace and why it matters here

Because two of this hero's phrases share no common prefix while others might, smartBackspace: true tells Typed.js to only delete the characters that differ between the current string and the next one, rather than deleting the entire string down to nothing and retyping from scratch. For phrases that do share a prefix, this produces a subtly smarter, faster transition; when there's no shared prefix (as here) it behaves the same as a full backspace.

A custom CSS caret instead of Typed's own

Typed.js can render its own blinking cursor span, but this snippet sets showCursor: false and supplies a separate .tjh-caret element animated with a plain CSS @keyframes blink instead — this keeps the caret's exact color, width, and blink timing fully controllable in CSS rather than through Typed's cursor options, and avoids any layout shift from Typed inserting and removing its own cursor markup.

Customizing it

Add or remove phrases in the strings array, tune typeSpeed/backSpeed/backDelay for a snappier or more deliberate rhythm, or pair this hero with a Hero Section layout below featuring the specific audience the current phrase describes.

Build with AI

Build, Understand, Optimize, and Extend It With AI

You don't have to write the typing/deleting interval logic by hand. Paste this snippet's HTML, CSS, and JS into an AI coding assistant like Claude and ask it to explain exactly how Typed.js sequences through the strings array using typeSpeed, backSpeed, and backDelay, and what smartBackspace changes about the deletion behavior when consecutive phrases share a prefix. The same assistant can help you tune the rhythm — asking whether the current 48ms type speed and 1400ms read pause feel right for a five-phrase rotation, or whether shorter phrases should get a shorter backDelay than longer ones. It's also useful for extending the hero: ask it to defer starting the Typed.js instance until the hero scrolls into view using an IntersectionObserver, swap the custom CSS caret's color per phrase, or add a fade transition between phrases in addition to the type/delete effect. Treat the code less like a finished artifact and more like a starting point for a conversation.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a hero section with a headline that cycles through multiple strings using a realistic type-then-delete animation, powered by the Typed.js library loaded from a CDN.

Requirements:
- A hero section with an eyebrow label, a large heading containing an empty inline span reserved for the typed text plus a separately styled blinking caret element, a supporting paragraph, and two call-to-action buttons.
- Initialize a single new Typed(selector, options) instance targeting the empty span, passing an array of at least five distinct phrases as the strings option.
- Configure typeSpeed and backSpeed as two different numeric values (typing should generally feel a bit slower than deleting), a backDelay controlling how long a fully-typed phrase pauses before deletion begins, and loop: true so the cycle repeats indefinitely through all phrases.
- Enable smartBackspace so that if two consecutive phrases in the array happen to share a prefix, Typed.js only deletes the differing suffix rather than deleting the entire phrase down to nothing.
- Disable Typed.js's own built-in cursor (showCursor: false) and instead implement a separate caret element styled and animated purely with CSS (a simple opacity blink via @keyframes), positioned immediately after the typed text span.
- Apply a CSS gradient text effect (background-clip: text) to the typed span so the cycling phrase itself is visually distinct from the static portion of the headline.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Step by step

How to Use

  1. 1
    Add the Typed.js CDN scriptInclude typed.umd.js from the CDN panel.
  2. 2
    Paste HTML, CSS, and JSA hero with an empty typed span and blinking caret renders.
  3. 3
    Watch the headline typeThe first phrase types out character by character.
  4. 4
    Watch it pause, then deleteAfter backDelay, it backspaces before typing the next phrase.
  5. 5
    Let it loopAll five phrases cycle continuously since loop is true.
  6. 6
    Edit the strings arrayReplace the five phrases with your own audiences or value props.

Real-world uses

Common Use Cases

Multi-audience SaaS heroes
Cycle through customer segments in a Hero Section.
Recruiting / careers pages
Rotate through roles or values a company hires for.
Personal portfolio intros
Cycle job titles or skills, similar to Typewriter.
Agency landing pages
Rotate industries or services the agency specializes in.
Product positioning pages
Show several use cases for one product without separate heroes.
App onboarding intros
Cycle through feature highlights before the sign-up flow.
Related: Hero with Animated Stat Counters
See the Hero with Animated Stat Counters for a related heroes pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

The strings array is processed in order: Typed.js types out the current string one character at a time at typeSpeed, waits for backDelay once fully typed, deletes it at backSpeed, then advances to the next string in the array. Once the last string has been typed, deleted, and loop is true, it restarts from the first string, creating a continuous cycle.

Without it, Typed.js deletes a finished string down to zero characters before typing the next one from scratch. With smartBackspace: true, if the next string in the array shares a prefix with the current one, Typed.js only deletes the differing suffix and types the new suffix — producing a faster, subtly smarter-feeling transition for phrases that share common wording.

Typed.js can render and animate its own cursor element automatically, but this snippet opts out of that (showCursor: false) and instead renders a separate .tjh-caret span animated with a plain CSS @keyframes blink. This gives full control over the caret's exact width, color, and blink timing directly in CSS rather than through Typed's more limited cursor styling options.

Yes — instead of constructing new Typed(...) immediately on page load, wrap the construction in an IntersectionObserver callback watching the hero section, and only call new Typed('#tjhTyped', {...}) once the hero becomes visible. This defers the animation start until a visitor actually scrolls to it.

Install the typed.js npm package (or keep the CDN script), import Typed, and construct new Typed(selector, options) inside a mount effect (useEffect, onMounted, or ngAfterViewInit) targeting a ref to the span element. Call the returned instance's .destroy() method in the cleanup function to stop the typing loop and remove its DOM manipulation when the component unmounts.