> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vowen.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Text Expander

> Type short triggers that expand into longer text snippets.

<div style={{ marginTop: "-2.5rem" }}>
  <Info>Free plan includes built-in expansions plus 1 custom expansion. <a href="https://vowen.ai" className="font-semibold underline-offset-2" style={{ color: "#8b5cf6", backgroundColor: "rgba(139, 92, 246, 0.12)", border: "1px solid rgba(139, 92, 246, 0.35)", padding: "2px 8px", borderRadius: "6px", fontSize: "0.85em", textDecoration: "none", whiteSpace: "nowrap" }}>Pro</a> unlocks unlimited custom expansions.</Info>
</div>

## What is Text Expander?

Text Expander lets you type a short trigger (like `:date`) anywhere on your computer and have it automatically expand into longer text. This works globally, in any app and any text field.

<div className="my-6 rounded-2xl border border-zinc-200 dark:border-zinc-800 p-2">
  <div style={{ position: "relative", background: "#000", borderRadius: "0.5rem", overflow: "hidden" }}>
    <video
      muted
      playsInline
      preload="metadata"
      poster="/videos/text-expander-demo-poster.jpg"
      style={{ width: "100%", display: "block", cursor: "pointer" }}
      onLoadedMetadata={(e) => { try { e.currentTarget.currentTime = 2; } catch (err) {} }}
      onClick={(e) => {
    const v = e.currentTarget;
    if (v.paused) { v.muted = false; v.play(); } else { v.pause(); }
  }}
      onPlay={(e) => {
    const parent = e.currentTarget.parentElement;
    const playBtn = parent.querySelector('[data-play-btn]');
    if (playBtn) { playBtn.style.opacity = '0'; playBtn.style.pointerEvents = 'none'; }
    const muteBtn = parent.querySelector('[data-mute-btn]');
    if (muteBtn) {
      muteBtn.querySelector('[data-icon-muted]').style.display = 'none';
      muteBtn.querySelector('[data-icon-unmuted]').style.display = 'block';
    }
  }}
      onPause={(e) => {
    const playBtn = e.currentTarget.parentElement.querySelector('[data-play-btn]');
    if (playBtn) { playBtn.style.opacity = '1'; playBtn.style.pointerEvents = 'auto'; }
  }}
    >
      <source src="https://mintcdn.com/vowen/2NLLQOm5sszam2ni/videos/text-expander-demo.mp4?fit=max&auto=format&n=2NLLQOm5sszam2ni&q=85&s=1849cdd282ffbfbd71dbbd0596932398" type="video/mp4" data-path="videos/text-expander-demo.mp4" />
    </video>

    <button
      data-play-btn
      aria-label="Play video"
      onClick={(e) => {
    const v = e.currentTarget.parentElement.querySelector('video');
    v.muted = false; v.play();
  }}
      style={{ position: "absolute", top: "50%", left: "50%", transform: "translate(-50%, -50%)", width: "72px", height: "72px", borderRadius: "9999px", background: "rgba(0,0,0,0.55)", border: "2px solid rgba(255,255,255,0.9)", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", transition: "opacity 0.2s ease", padding: 0 }}
    >
      <svg width="28" height="28" viewBox="0 0 24 24" fill="white" style={{ marginLeft: "4px" }}>
        <path d="M8 5v14l11-7z" />
      </svg>
    </button>

    <button
      data-mute-btn
      aria-label="Toggle mute"
      onClick={(e) => {
    e.stopPropagation();
    const v = e.currentTarget.parentElement.querySelector('video');
    v.muted = !v.muted;
    e.currentTarget.querySelector('[data-icon-muted]').style.display = v.muted ? 'block' : 'none';
    e.currentTarget.querySelector('[data-icon-unmuted]').style.display = v.muted ? 'none' : 'block';
  }}
      style={{ position: "absolute", top: "0.75rem", right: "0.75rem", background: "rgba(0,0,0,0.55)", border: "none", borderRadius: "9999px", width: "36px", height: "36px", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", padding: 0 }}
    >
      <svg data-icon-muted width="16" height="16" viewBox="0 0 24 24" fill="white" style={{ display: "block" }}>
        <path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27 7.73 9H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.17v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z" />
      </svg>

      <svg data-icon-unmuted width="16" height="16" viewBox="0 0 24 24" fill="white" style={{ display: "none" }}>
        <path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z" />
      </svg>
    </button>
  </div>
</div>

## Built-in Expansions

| Trigger | Expands To   | Example Output |
| ------- | ------------ | -------------- |
| `:date` | Current date | 2026-05-10     |
| `:time` | Current time | 14:30          |

## Creating Custom Expansions

1. Open the Vowen app and click **Dictionary** in the left sidebar
2. Switch to the **Expansions** tab
3. Click **+ Add Expansion**
4. Enter your trigger (e.g., `:addr`) and replacement text (e.g., "123 Main Street, Suite 400, New York, NY 10001")
5. Click Save

New custom expansions open in the **Rich** editor by default, so you can keep bold, links, lists, and other formatting in the expanded text. Use the **Plain/Rich** toggle in the editor if you'd rather store the expansion as plain text. (The built-in `:date` and `:time` are always plain.)

## How It Works

1. You type the trigger characters (e.g., `:email`)
2. Vowen detects the completed trigger
3. It simulates backspaces to delete the trigger
4. It pastes the replacement text

This happens in real-time as you type, no shortcut needed.

## Use Cases

* **Contact info:** `:email` → your email address
* **Signatures:** `:sig` → your full email signature
* **Boilerplate:** `:thanks` → "Thank you for your message. I'll get back to you shortly."
* **Links:** `:gh` → your GitHub profile URL
* **Date/Time:** `:date` → today's date (built-in)

## Managing Expansions

* **Enable/Disable:** toggle individual expansions without deleting them
* **Edit:** change the trigger or replacement text
* **Delete:** remove custom expansions (built-ins cannot be deleted)
* **Built-in label:** shows which expansions are system-provided
* **Search:** filter the list by shortcut or text with the search bar at the top
* **Tags:** label expansions with colored tags, then use the tag filter bar (with any/all match modes) and sort options to organize a large library

## Suggestions Dropdown

Turn on **Show suggestions dropdown** at the top of the Expansions tab and Vowen shows a live picker as you type a `:` trigger. Matching expansions appear in a small list near your cursor; click one to insert it without stealing focus from the app you're typing in — handy when you can't remember the exact shortcut. It's off by default.

## Bulk Import

Building dozens of expansions one-by-one in the app is slow. You can prepare a JSON file with all of them (plain text or rich HTML) and import it in one click — see [Import & Export Data](/features/import-data) for the file format and an LLM-ready prompt that converts any source list (spreadsheet, Word doc, wiki) into a ready-to-import file.

## Behavior Notes

* Expansions are **paused during voice recording** (won't interfere with transcription)
* A **mouse click resets** the trigger buffer (starts fresh)
* Triggers are **case-sensitive**
* The trigger prefix `:` is not configurable currently
