# defineTextTrack

Define a text track once, with the type of its cue values, to add and read it with

## Import

```ts
import { defineTextTrack } from '@videojs/html';
```

`defineTextTrack` returns a track definition: a track’s `kind`, and optionally its `label` and `language`, typed with the `value` its cues carry. A definition works anywhere a text track filter does, matching tracks by kind, label, and language. Reading through it types each cue’s `value`, and adding a track from it checks the cues you pass against that type.

## Usage

Pass the value type as a type parameter. The type isn’t checked at runtime.

```ts
import { defineTextTrack, getActiveTextCues, type TextCueInit } from '@videojs/html';

interface Quiz {
  question: string;
}

const quizTrack = defineTextTrack<Quiz>({ kind: 'metadata', label: 'quiz' });

const player = document.querySelector('video-player')!;
const cues: TextCueInit<Quiz>[] = await fetch('/api/quiz').then((res) => res.json());

player.store.addTextTrack(quizTrack, { cues });

player.store.subscribe(() => {
  const [cue] = getActiveTextCues(player.store, quizTrack);
  console.log(cue?.value?.question);
});
```

### Schemas

Pass a `schema` to check values where they’re read. It takes any [Standard Schema](https://standardschema.dev), the validation interface zod, valibot, ArkType, and other libraries implement, and the value type comes from the schema’s output.

```ts
import { z } from 'zod';

const QuizSchema = z.object({ question: z.string() });

const quizTrack = defineTextTrack({ kind: 'metadata', label: 'quiz', schema: QuizSchema });
```

Readers skip a cue whose value fails the schema, and warn in development. Each cue is checked once per schema. Schemas must be synchronous; an asynchronous schema fails every value. Adding a track doesn’t run the schema.

### Built-in definitions

[`chaptersTrack`](https://videojs.org/docs/framework/html/reference/api/chapters-track) matches every chapters track and types the values chapter formats carry. [`hlsMetadataTrack`](https://videojs.org/docs/framework/html/reference/api/hls-metadata-track) matches the metadata track hls.js publishes ID3 and `EXT-X-DATERANGE` metadata on.

## Exports

| Export | Description |
| --- | --- |
| `TextTrackDefinition` | A track definition. Its type parameter is the cue type it reads. |
| `TextTrackIdentity` | What identifies a track: `kind`, `label`, and `language`. |
| `InferTextTrackCue` | The cue type a definition reads, as in `InferTextTrackCue<typeof quizTrack>`. |
| `InferSchemaOutput` | The value type a schema produces. |
| `StandardSchemaV1` | The Standard Schema interface a `schema` implements. |
| `StandardSchemaV1Props` | The properties a Standard Schema carries under its `~standard` key. |
| `StandardSchemaV1Result` | What a Standard Schema’s `validate` returns. |

## API Reference

### With Schema

`defineTextTrack<Schema extends StandardSchemaV1>(init): TextTrackDefinition<MediaTextCue<InferSchemaOutput<Schema>>>`

Define a text track whose cues carry a `value` checked by a schema, such as one from zod or valibot. Cues whose value fails it are skipped where they're read.

`const quizTrack = defineTextTrack({ kind: 'metadata', label: 'quiz', schema: QuizSchema });`

#### Parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `init` (required) | `{ kind: 'subtitles' \| 'captions' \| 'descriptions' \| 'chapters' \| 'metadata'; label?: string; language?: string } & { schema: Schema }` | — | The track's kind, and optionally its label and language, with a [Standard Schema](https://standardschema.dev) for its cue values. |

#### Return Value

| Property | Type | Description |
| --- | --- | --- |
| `kind` | `'subtitles' \| 'captions' \| 'descriptions' \| 'chapters' \| 'metadata'` | |
| `label` | `string \| undefined` | |
| `language` | `string \| undefined` | |
| `schema` | `{ ~standard: StandardSchemaV1Props<unknown, Input> } \| undefined` | Checks each cue's `value` where it's read. Cues whose value fails are skipped. |

### With Type

`defineTextTrack<Value = unknown>(init): TextTrackDefinition<MediaTextCue<Value>>`

Define a text track whose cues carry a `value` of a given type. The type is not checked at runtime; pass a `schema` for that.

`const quizTrack = defineTextTrack<Quiz>({ kind: 'metadata', label: 'quiz' });`

#### Parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `init` (required) | `{ kind: 'subtitles' \| 'captions' \| 'descriptions' \| 'chapters' \| 'metadata'; label?: string; language?: string }` | — | The track's kind, and optionally its label and language. |

#### Return Value

| Property | Type | Description |
| --- | --- | --- |
| `kind` | `'subtitles' \| 'captions' \| 'descriptions' \| 'chapters' \| 'metadata'` | |
| `label` | `string \| undefined` | |
| `language` | `string \| undefined` | |
| `schema` | `{ ~standard: StandardSchemaV1Props<unknown, Input> } \| undefined` | Checks each cue's `value` where it's read. Cues whose value fails are skipped. |

---

HTML documentation: https://videojs.org/docs/framework/html/llms.txt
All documentation: https://videojs.org/llms.txt
