WebVTT is the subtitle format browsers understand. It's the only one they understand: hand an SRT to an HTML5 video and nothing happens at all. No error, no warning, no subtitles.
The extension is .vtt and, inside, it looks a lot like an SRT. Three things change: a mandatory header, a dot where SRT puts a comma, and the ability to say far more than an SRT can.
What's inside
WEBVTT
1
00:00:04.120 --> 00:00:06.480
Let's go over where we are
before we get into detail.
2
00:00:06.600 --> 00:00:09.000 line:90% align:start
The number that surprised me most
was the second-week drop-off.
The first line has to be WEBVTT. If it's missing, if a byte-order mark comes before it, or if there's a blank line first, the browser discards the entire file.
After that, the same blocks as always, with two visible differences: milliseconds go after a dot, and the timing line can carry settings.
What it adds over an SRT
Position and alignment. line:90% drops the subtitle down, align:start pins it left, position:20% moves it sideways. Useful for not covering a caption that's already burned into the picture.
Styling. A STYLE block with real CSS at the top of the file, and classes inside the text with <c.narrator>. Colours, sizes, shadows.
Who's speaking. The <v Marta>Good morning</v> tag marks the voice. Players that understand it can colour it differently; players that don't just ignore it. In an interview or a meeting, that's the difference between a wall of text and something readable.
Notes and regions. NOTE blocks for comments nobody sees, and REGION for defining areas of the screen with their own scrolling — the way live captions roll up.
Cue identifiers. Each block can carry a name on the line above the timing — intro, question-3 — so you can point at it from JavaScript.
When you need a VTT
Whenever the video plays inside a browser. If your page has a <video> with a <track>, the file has to be WebVTT:
<video controls>
<source src="meeting.mp4" type="video/mp4" />
<track src="meeting.vtt" kind="subtitles" srclang="en" label="English" default />
</video>
The same goes for modern web players (Video.js, Plyr, Shaka) and for HLS streaming, which carries subtitles as WebVTT segments.
Outside the browser, almost nobody asks for it: desktop editors, long-standing players and most upload forms still expect an SRT.
Two things that break and aren't the file's fault
The server has to send it as text/vtt. Served as text/plain or application/octet-stream, some browsers drop it. You fix that in the server config, not in the file.
And it has to be same-origin, or carry CORS. A .vtt on another domain without Access-Control-Allow-Origin won't load, even though the URL works fine if you open it by hand. It's the number one cause of "the video plays but the subtitles don't".
Both are configuration problems and neither shows a visible error on the page. You see them in the network tab of the browser's dev tools, and only if you know to look there.
Converting it
SRT to VTT is straightforward: header, dot instead of comma, and escaping the & and < characters that an SRT carries as text and WebVTT would read as markup. Our SRT to VTT converter does all three in your browser, without uploading the file.
The other way round loses what SRT cannot express — position, styling, regions — so the VTT to SRT converter drops them and turns voice tags into a «Marta:» in front of the line, which is something an SRT can actually show. Which one to pick.
If what you have is the video and not the subtitles
Upload it and you'll get the transcript back with timestamps, the speakers separated and named, and a summary. The VTT falls out of that, voices marked and all. The first 45 seconds don't need an account.