---
name: vtt-cue-settings-timestamp-parse
description: VTT cue settings (line:0%, position:50%) appear in the timestamp line after the timecode — parser must strip everything after the first space following the arrow to extract the end time correctly
type: concept
---

# VTT Cue Settings — Timestamp Line Parsing

## WebVTT Cue Header Format

A VTT cue header has this structure:

```
00:00:01.500 --> 00:00:04.000 line:0% position:50% align:center
This is the cue text.
```

The timestamp line is: `START --> END [SETTINGS]`

Settings are optional and appear after the end time, separated by a space.

## The Parser Bug

A naive parser that splits on `-->` and trims gets:

```
"00:00:01.500"  and  "00:00:04.000 line:0% position:50% align:center"
```

If the end-time string is used directly in `Date.parse()` or a custom HH:MM:SS.ms parser, it will **fail silently or produce NaN** because of the trailing settings string.

```ts
// WRONG
const [start, end] = line.split(' --> ')
const endMs = parseTimestamp(end)  // end = "00:00:04.000 line:0%..." → NaN
```

## The Fix

Strip everything after the first space in the end-time segment:

```ts
const [start, endWithSettings] = line.split(' --> ')
const end = endWithSettings.split(' ')[0]  // ← strip cue settings
const endMs = parseTimestamp(end.trim())   // "00:00:04.000"
```

Or with a regex:

```ts
const match = line.match(/^(\S+)\s+-->\s+(\S+)/)
// match[1] = start, match[2] = end (stops at first whitespace)
```

## Settings Round-Trip Loss

If you parse a VTT file and rebuild it, cue settings are lost unless explicitly preserved:

```ts
interface VttCue {
  start: number
  end: number
  settings: string  // ← store the raw settings string
  text: string
}

// On parse:
const settings = endWithSettings.includes(' ')
  ? endWithSettings.slice(endWithSettings.indexOf(' ') + 1)
  : ''

// On rebuild:
const line = `${formatTime(cue.start)} --> ${formatTime(cue.end)}${cue.settings ? ' ' + cue.settings : ''}`
```

## Common VTT Cue Settings

| Setting | Example | Effect |
|---------|---------|--------|
| `line` | `line:0%` | Vertical position (0%=top, 100%=bottom) |
| `position` | `position:50%` | Horizontal position |
| `align` | `align:center` | Text alignment |
| `size` | `size:80%` | Cue box width |

**Source:** daily/2026-05-13.md | 2026-05-13
