Best subtitle format for Video.js
TL;DR — Discover why WebVTT is the best format for Video.js. Learn when to convert SRT and how to fix common caption issues. Free tools and troubleshooting guide.
Related tool
SRT to VTT Converter
For most Video.js subtitle workflows, WebVTT (VTT) is the safest default format. Video.js runs in the browser, so caption delivery should follow browser-friendly subtitle rules. SRT can be a good source format, but WebVTT is the safer final file for player integration.
Quick answer
If your source subtitles are in SRT, convert them to VTT before attaching them to Video.js. That keeps your caption workflow aligned with the format most commonly expected in web playback.
Use the Video.js Subtitle Converter to create VTT output from SRT or ASS input.
Why VTT fits Video.js better
Video.js sits in a browser-first environment, so it benefits from the subtitle format designed for that environment. WebVTT is a good match because it:
- Built for web playback: WebVTT is the W3C standard for HTML5 video captions
- Browser-native parsing: Browsers have built-in WebVTT parsers, so rendering is faster and more reliable
- WEBVTT header: The
WEBVTTheader signals to the browser that the file is a valid caption track - Dot-based timestamps:
00:00:01.000(dots) match JavaScript time formats, unlike SRT’s comma-based00:00:01,000 - Advanced features: WebVTT supports cue settings (alignment, position, size), styling, and metadata that SRT doesn’t
It also gives developers a cleaner debugging path. If the VTT file is valid, caption issues are more likely to come from the player setup, track configuration, or how the file is served - not the subtitle format itself.
Video.js subtitle support by format
| Format | Video.js Support | Browser Support | Notes |
|---|---|---|---|
| VTT | ✅ Native | ✅ All browsers | Recommended, best compatibility |
| SRT | ⚠️ Plugin required | ❌ Not native | Needs conversion or plugin |
| ASS/SSA | ❌ Not supported | ❌ Not native | Convert to VTT first |
Key takeaway: Video.js works best with VTT. SRT requires a plugin or conversion. ASS is not supported at all. For the complete conversion workflow, see how to convert subtitles for Video.js.
When SRT still appears
SRT still shows up because it’s common in:
- Exports from transcription tools: Many transcription services (Rev, Otter, Descript) export SRT by default
- Old subtitle archives: Legacy subtitle files from DVD rips, fansubs, or older projects
- Handoffs from collaborators: Translators, editors, or clients may send SRT files
That doesn’t make it the best final delivery format for a browser player.
Use SRT for: Review, translation, editing, or archive. Convert to VTT before wiring it into Video.js.
Video.js caption checklist
Before adding captions to Video.js, check:
- ✅ Format: Use a
.vttfile for browser playback - ✅ Header: File begins with
WEBVTT(uppercase, first line) - ✅ Timestamps: Use dots (
00:00:01.000), not commas (00:00:01,000) - ✅ Encoding: Use UTF-8 encoding to avoid character corruption
- ✅ URL: Serve the caption file from a URL the page can request (not a local file path)
- ✅ CORS: If the VTT file is on a different domain, the server must send
Access-Control-Allow-Originheaders - ✅ MIME type: Server must send
Content-Type: text/vtt(nottext/plainorapplication/octet-stream) - ✅ Testing: Test with the same Video.js setup that will be used in production
Practical workflow
Scenario 1: You have SRT subtitles
- Keep the source SRT file if you may need to edit it later
- Convert to VTT using the SRT to VTT Converter
- Validate the VTT file with the WebVTT Validator
- Upload the VTT file to your web server or CDN
- Add the VTT file to Video.js:
<video id="my-video" class="video-js" controls preload="auto">
<source src="video.mp4" type="video/mp4" />
<track kind="subtitles" src="captions.en.vtt" srclang="en" label="English" default />
</video>
- Test playback in the browser and verify captions appear
What changes: Timestamp format (commas → dots), file header added (WEBVTT). Text content stays the same.
Scenario 2: You have ASS subtitles (anime, fansubs, styled captions)
- Convert ASS to VTT using the ASS to VTT Converter
- Validate the VTT file
- Upload and test
What you lose: Advanced styling (colors, fonts, positioning, karaoke effects). WebVTT supports basic cue settings (alignment, position) but not ASS-level styling.
What you gain: Browser compatibility, faster rendering, easier debugging.
Scenario 3: You have multiple subtitle languages
Add multiple <track> elements with different srclang and label attributes:
<video id="my-video" class="video-js" controls preload="auto">
<source src="video.mp4" type="video/mp4" />
<track kind="subtitles" src="captions.en.vtt" srclang="en" label="English" default />
<track kind="subtitles" src="captions.es.vtt" srclang="es" label="Español" />
<track kind="subtitles" src="captions.fr.vtt" srclang="fr" label="Français" />
</video>
Video.js automatically detects all tracks and displays them in the captions menu.
Scenario 4: You need to serve VTT from a CDN
If your VTT file is on a different domain than the video page, configure CORS:
Server-side (CDN or origin server):
Access-Control-Allow-Origin: https://yourdomain.com
Content-Type: text/vtt; charset=utf-8
Client-side (HTML):
<video crossorigin="anonymous">
<track src="https://cdn.example.com/captions.en.vtt" />
</video>
Without both, the browser blocks the VTT request and captions fail silently.
Common mistakes
Treating every subtitle file as interchangeable
Two files can contain the same lines and timing but still behave differently in browser playback because their formats differ. SRT and VTT are not interchangeable - browsers expect VTT.
Fix: Always convert SRT to VTT before using it in Video.js. See how to convert SRT to VTT for HTML5 video for step-by-step instructions.
Renaming SRT to VTT without converting
Renaming captions.srt to captions.vtt does not convert the file. The browser sees SRT-style timestamps (commas) and no WEBVTT header, so it rejects the file.
Fix: Use the SRT to VTT Converter to properly convert the file.
Testing only in a text editor
A subtitle file that looks fine in a text editor can still fail in the player due to:
- Wrong MIME type from the server
- CORS issues (cross-origin requests blocked)
- Encoding problems (non-UTF-8 characters)
- Malformed timestamps or cue structure
Fix: Always test the final file in the real playback environment (Video.js in a browser).
Shipping the source file instead of the delivery file
Keep the SRT or ASS source if it helps the workflow, but ship the VTT file to Video.js unless your implementation has a specific reason to do otherwise.
Fix: Use SRT for editing and translation, but convert to VTT for browser delivery.
Forgetting CORS headers for cross-origin VTT files
If your video page is at example.com and the VTT file is at cdn.example.com, the browser blocks the request unless the server sends Access-Control-Allow-Origin headers.
Fix: Configure CORS on the CDN or origin server, and add crossorigin="anonymous" to the <video> element.
Using the wrong MIME type
If the server sends Content-Type: text/plain or application/octet-stream, the browser refuses to parse the file as WebVTT.
Fix: Configure the server to send Content-Type: text/vtt for .vtt files. See How to fix VTT MIME type for HTML5 video for server-specific instructions.
Troubleshooting scenarios
Scenario 1: Captions don’t appear in Video.js
Possible causes:
- VTT file is malformed (missing
WEBVTTheader, wrong timestamp format) - Server sends wrong MIME type (
text/plaininstead oftext/vtt) - CORS headers missing (cross-origin request blocked)
- Track element has wrong
srcURL (404 error)
Fix:
- Validate the VTT file with the WebVTT Validator
- Check the browser console for errors (F12 → Console tab)
- Check the Network tab for the VTT request - verify it returns 200 OK and
Content-Type: text/vtt - If cross-origin, verify CORS headers and
crossorigin="anonymous"attribute
For Video.js-specific issues, see why Video.js captions are not showing. For a broader troubleshooting walkthrough, see Why subtitles do not show in HTML5 video.
Scenario 2: Captions appear but text is garbled
Cause: Wrong text encoding (e.g., Windows-1252 instead of UTF-8).
Fix: Re-save the VTT file as UTF-8 in a text editor before uploading.
Scenario 3: Captions work in Chrome but not Firefox or Safari
Cause: Firefox and Safari are stricter about MIME types and CORS than Chrome.
Fix:
- Confirm
Content-Type: text/vtt(nottext/plain) - If cross-origin, ensure
Access-Control-Allow-Originis set - Check the browser console for specific error messages
Scenario 4: Captions are out of sync
Cause: The subtitle file was created for a different video cut, or timestamps are wrong.
Fix: Use the Subtitle Time Shifter to adjust timing, or re-sync the subtitles to match your video.
Scenario 5: Captions show briefly then disappear
Cause: Track loads but the cue parser fails partway through the file due to malformed cues.
Fix: Re-validate the VTT file. Look for malformed cues in the middle of the file - a single bad timestamp can break everything that follows.
Frequently asked questions
Does Video.js support SRT natively?
No. Video.js relies on the browser’s native <track> element, which only supports WebVTT. To use SRT, you need a plugin or conversion.
Can I use SRT with a Video.js plugin?
Yes, but it’s not recommended. Plugins add complexity, increase bundle size, and may have compatibility issues. Converting SRT to VTT is simpler and more reliable.
What’s the difference between VTT and SRT?
| Difference | SRT | VTT |
|---|---|---|
| Header | None | WEBVTT required |
| Timestamps | 00:00:01,000 (comma) | 00:00:01.000 (dot) |
| Browser support | ❌ Not native | ✅ Native |
| Cue settings | ❌ Not supported | ✅ Alignment, position, size |
| Styling | Limited HTML tags | CSS-like cue settings |
Can I style VTT captions in Video.js?
Yes. WebVTT supports cue settings (alignment, position, size) and CSS styling via ::cue pseudo-elements. Video.js also provides its own caption styling API.
How do I add chapters or thumbnails with VTT?
Use kind="chapters" or kind="metadata" in the <track> element:
<track kind="chapters" src="chapters.vtt" srclang="en" />
<track kind="metadata" src="thumbnails.vtt" />
What if my VTT file has a BOM (Byte Order Mark)?
Some text editors (Notepad on Windows) save UTF-8 files with a BOM - 3 invisible bytes at the start. The WebVTT parser sees this as garbage before WEBVTT and rejects the file.
Fix: Re-save the file as “UTF-8 without BOM” in your editor.
Can I use VTT for live streaming?
Yes. WebVTT supports live streaming via HLS (HTTP Live Streaming) or DASH (Dynamic Adaptive Streaming over HTTP). Video.js handles live VTT captions automatically when using HLS or DASH sources.
Related guides
- Best subtitle format for HTML5 video
- SRT vs VTT
- How to convert SRT to VTT for HTML5 video
- How to fix VTT MIME type for HTML5 video
- Why Video.js captions are not showing
- How to convert subtitles for Video.js
Related tools
Use the SRT to VTT Converter
Convert SRT subtitles to WebVTT online for HTML5 video, browser players, and track elements. No signup, no upload, and everything runs locally in the browser.
Open SRT to VTT