---
title: SC Typewriter Title
description: Types and erases rotating phrases next to a fixed title.
url: https://secretocho.design/lab/sc-typewriter-title/
type: SoftwareSourceCode
status: working
published: 2025-09-01
updated: 2025-09-01
---

# SC Typewriter Title

> Types and erases rotating phrases next to a fixed title.

component 05 / 28 · WORKING

- **type**: Code Component
- **platform**: Framer
- **last update**: 2025-09-01
- **license**: SecretoCho Design

![A still of the SC Typewriter Title demo, as its module draws it with reduced motion.](https://secretocho.design/_astro/still.CkTf6drd_ZpINv7.webp)

*fig 00 · live demo, ported from **SC\_TypewriterTitle.tsx***

Type & erase rotating phrases next to a fixed title—fast to configure, accessible, and performant.

A configurable typewriter headline for Framer. Displays a fixed lead-in plus a rotating list of phrases, typed and erased with a blinking caret. Tunable typing speed, hold time, caret style, layout (inline/stacked), and full typography controls.

- UI
- Typography
- Text
- Motion

## Main

### Overview

- **Built With**: React (hooks), CSS (inline), Framer Code Component API
- **Layout Support**: Responsive; inline or vertical stacking
- **Orientation**: Text-only, left-to-right sequence
- **Ideal Use Case**: Hero headings, landing page taglines, product slogans

### Tags

- typewriter
- headline
- caret
- animated text
- rotating phrases

### Code comment

```tsx
/*
 * SC Typewriter Title
 * © SecretoCho Design 2025 (https://secretocho.design)
 * A flexible headline that types & deletes rotating phrases with a blinking caret.
 * Time-based state machine using setTimeout/setInterval; no heavy libs.
 * @framerDisableUnlink
 * @framerIntrinsicWidth 480
 * @framerIntrinsicHeight 120
 */
```

### Dependencies

- **Technologies**: None (pure React + timers)
- **Notes**: No external motion libraries; uses setTimeout/setInterval.

### Complexity

- **Logic Level**: Medium (typed/deleted state machine, timers, looping)
- **Runtime Cost**: Very Low (string slicing; no RAF)
- **Component Size**: ~3–4 KB TSX
- **Notes**: Timers are cleaned on unmount to prevent leaks.

## Guide

### Instructions

1. Add to your Framer project and place on the canvas.
2. Set **Fixed Text** (mainTitle) and **Rotating Phrases** (animatedTitles).
3. Adjust **Typing Speed**, **Display Duration (hold)**, **Initial Delay**, and **Repeat**.
4. Style with **Typography**, **Fixed/Animated Text Color**, and **Cursor Style**.
5. Choose **Text Arrangement**: inline (side-by-side) or stacked (new line).

### Examples / Presets

- Preset A – Default Hero
  
  “Designs that” + phrases: “convert & captivate” … speed=60ms, hold=1600ms, caret |
  
- Preset B – Fast Tagline
  
  - **speed**: 30ms
  - **hold**: 800ms
  - **blink**: 300ms
  - **layout**: inline
  
- Preset C – Minimal Stacked
  
  layout=stacked, fontSize=32, caret \_, colors: main #111, animated #555
  

## Mechanics

### How it Works

- Maintains index (phrase), subIndex (char position), and deleting flags.
- Typing/deleting steps scheduled with setTimeout(typeSpeed).
- After fully typed, waits holdTime then switches to deleting.
- On reaching 0 chars, advances to next phrase; loops if loop=true.
- Caret blinking toggled via setInterval(caretBlinkSpeed); blink is CSS opacity.

### Performance & Tuning

- Typing uses setTimeout; no layout thrash; safe for most devices.
- Smaller **typeSpeed** = faster typing; tune **holdTime** for rhythm.
- Long strings are fine; avoid extremely large phrase arrays for readability.

### Compatibility & Limits

- Modern browsers; no WebGL/RAF required.
- Uses inline styles; adopt tokens if you need theme-wide control.
- Text renders as real DOM text (copyable/selectable).

## Quality

### Accessibility

- Pure text output; readable by screen readers.
- Motion sensitivity: consider exposing a toggle or respecting prefers-reduced-motion (pause typing & caret).
- Ensure color contrast for both fixed and animated text.

### Security & Privacy

- No network calls or storage.
- No dangerouslySetInnerHTML or eval.
- All timers are cleared on unmount.

## Reference

### Props

| name | type | default | description |
| --- | --- | --- | --- |
| mainTitle | string | “Designs that” | Static lead-in text that never changes. |
| animatedTitles | string | “convert & captivate” | Array of phrases to type and erase in order. |
| font | FontStyle | family:“Inter” | Typography for both fixed and animated segments. |
| mainColor | color | ”#000000” | Color for the fixed text. |
| animatedColor | color | ”#333333” | Color for the animated text. |
| caretChar | enum | ”\|” | Caret glyph used during typing. |
| caretBlinkSpeed | number | 500 | Blink interval for caret visibility. |
| typeSpeed | number | 60 | Delay between each typed/deleted character. |
| holdTime | number | 1600 | Time to keep a phrase fully typed before deleting. |
| startDelay | number | 300 | Initial wait before starting the typing cycle. |
| loop | boolean | true | If false, stops after the last phrase. |
| layout | enum | “inline” | Inline places phrases next to the fixed text; stacked puts them on a new line. |

### Notes & Tips

- Shorter, high-impact phrases work best for scanning.
- For tighter layouts, reduce fontSize and set layout="stacked".
- To pause after the last phrase (non-loop), set loop=false.

### Troubleshooting / FAQ

Caret not blinking

Check caretBlinkSpeed (\>0) and that component is mounted.

Animation never starts

Ensure startDelay isn’t too high; confirm animatedTitles isn’t empty.

Stops on last phrase

Expected when loop=false.

## Source

### Header comment

*SC\_TypewriterTitle.tsx · lines 4–14 · header comment*

```tsx
/*
 * TypewriterTitle.tsx – Framer Code Component
 * -----------------------------------------------------------
 * A highly‑configurable headline that reveals an array of sub‑titles
 * via a typewriter animation + blinking caret.
 *
 * © SecretoCho Design – July 2025
 * @framerDisableUnlink
 * @framerIntrinsicWidth 480
 * @framerIntrinsicHeight 120
 */
```

[props \[REF\]](#reference)

### Key excerpt

One step function: type to the end, hold, delete to the start, then move to the next phrase; a timer re-arms it at the typing speed.

*SC\_TypewriterTitle.tsx · lines 65–97 · tsx*

```tsx
    // ---------------------------------------------------------
    const step = useCallback(() => {
        const phrase = animatedTitles[index] || ""
        const atEnd = subIndex === phrase.length
        const atStart = subIndex === 0

        if (atEnd && !deleting) {
            // hold before deleting
            typeTimer.current = setTimeout(() => setDeleting(true), holdTime)
            return
        }
        if (atStart && deleting) {
            // next phrase / loop
            setDeleting(false)
            setIndex((prev) => {
                const next = prev + 1
                if (next < animatedTitles.length) return next
                return loop ? 0 : prev
            })
            return
        }
        // continue typing or deleting
        setSubIndex((prev) => prev + (deleting ? -1 : 1))
        typeTimer.current = setTimeout(step, typeSpeed)
    }, [animatedTitles, deleting, holdTime, index, loop, subIndex, typeSpeed])

    // Start typing
    useEffect(() => {
        typeTimer.current = setTimeout(step, startDelay)
        return () => {
            if (typeTimer.current) clearTimeout(typeTimer.current)
        }
    }, [step, startDelay])
```

## Credits

### Credits

Implementation & Framer adaptation by SecretoCho Design.

- **license**: SecretoCho Design

SecretoCho Design 2025

### Disclaimer

Provided “as is” for visual/UX purposes. Validate accessibility (contrast, motion), and performance within your layout.

## Proves

- [Creative coding](https://secretocho.design/about/#capabilities)

## Hiring a design engineer?

I’m open to senior design engineer roles: remote from Belgrade, or relocation with visa sponsorship. Write to me, or read the CV first. Client work stays selective, one project at a time.

[sc@secretocho.design](mailto:sc@secretocho.design)

[read the CV](https://secretocho.design/cv/) · [LinkedIn](https://www.linkedin.com/in/secretocho/)
