Subtitle guide Workflow guides

Why JW Player captions are not showing


TL;DR — Fix JW Player captions that do not show by checking VTT formatting, caption file URLs, player tracks, MIME type, and CORS settings.

Related tool

JW Player Subtitle Converter

Open JW Player converter

JW Player caption failures are usually caused by the caption file format, the URL path, or the player track configuration. This guide helps you diagnose and fix caption issues systematically.

Quick answer

Prepare a clean WebVTT file, validate it, and attach the correct VTT URL in the JW Player caption configuration. JW Player requires WebVTT format and proper CORS headers if captions are hosted on a different domain.

Use the JW Player Subtitle Converter when your source subtitles are SRT or ASS.

Why JW Player captions fail

JW Player is widely used for video hosting and streaming, but caption setup can be tricky. Common failure points:

  1. File format issues - Using SRT instead of VTT, or malformed WebVTT syntax
  2. URL problems - Broken paths, 404 errors, or incorrect file locations
  3. CORS blocking - Cross-origin restrictions preventing caption file access
  4. Player configuration - Missing or incorrect track setup in JW Player initialization
  5. Server issues - Wrong MIME type or missing response headers

Understanding which category your issue falls into saves debugging time.

Checklist

Before changing player code, systematically check these items:

File format checks

  • ✅ The file is WebVTT (.vtt), not renamed SRT
  • ✅ The VTT file starts with exactly WEBVTT on line 1
  • ✅ Timestamps use dots for milliseconds: 00:00:01.000 not 00:00:01,000
  • ✅ Blank line exists after the WEBVTT header
  • ✅ Cues are separated by blank lines

URL and server checks

  • ✅ The VTT URL returns a 200 OK response (test by opening it directly)
  • ✅ The file path is correct (no typos, correct directory)
  • ✅ Server returns correct MIME type (text/vtt or text/plain)
  • ✅ CORS headers allow the player page to load the file
  • ✅ HTTPS is used if the player page is HTTPS

Player configuration checks

  • ✅ The caption track is included in the JW Player setup object
  • ✅ The file property points to the correct VTT URL
  • ✅ The label property is set (what users see in the menu)
  • ✅ The kind property is set to "captions" or "subtitles"
  • ✅ At least one track has "default": true if you want captions on by default

If all checks pass but captions still don’t show, see the troubleshooting section below.

Step-by-step workflow

1. Convert source subtitles to VTT if needed

JW Player requires WebVTT format. If you have SRT or ASS files, convert them first.

Using the converter:

  1. Go to JW Player Subtitle Converter
  2. Upload or paste your SRT/ASS file
  3. Convert to WebVTT
  4. Download the .vtt file

What the converter does:

  • Adds the WEBVTT header
  • Converts comma timestamps to dot format
  • Removes SRT cue numbers (VTT doesn’t need them)
  • Ensures proper blank line spacing

2. Validate the VTT file

Even after conversion, validate to catch any syntax errors.

Steps:

  1. Open the WebVTT Validator
  2. Upload your VTT file
  3. Fix any reported errors
  4. Re-validate until it passes

Common validation errors:

  • Missing WEBVTT header
  • Comma instead of dot in timestamps
  • Missing blank lines between cues
  • Invalid cue separator (must be -->)

3. Open the deployed VTT URL directly

Before testing in the player, confirm the file is accessible.

Steps:

  1. Copy the VTT URL from your JW Player configuration
  2. Paste it into your browser address bar
  3. Press Enter

What you should see:

  • The VTT file content displays as plain text
  • First line shows WEBVTT
  • Timestamps and captions are visible

If you see an error:

  • 404 Not Found → File path is wrong or file wasn’t uploaded
  • 403 Forbidden → Check file permissions
  • CORS error → See step 5 below
  • Blank page → File might be empty or corrupted

4. Check network requests in browser developer tools

Use DevTools to see exactly what’s happening when the player loads.

Steps:

  1. Open your page with the JW Player
  2. Press F12 to open DevTools
  3. Go to the Network tab
  4. Reload the page
  5. Filter by “vtt” or search for your caption filename
  6. Click on the VTT request

What to check:

  • Status code: Should be 200 OK
  • Content-Type header: Should be text/vtt or text/plain
  • Response body: Should show the VTT file content
  • CORS headers: If cross-origin, check for Access-Control-Allow-Origin

Common issues:

  • Status 404 → Wrong URL in player config
  • Status 403 → Permission denied
  • Status 0 or (failed) → CORS blocking the request
  • Wrong Content-Type → Server misconfiguration

5. Fix CORS if needed

If your VTT file is on a different domain than your player page, CORS must allow it.

Symptom: Console error like:

Access to fetch at 'https://cdn.example.com/captions.vtt' 
has been blocked by CORS policy

Fix: Add CORS headers to your caption file server.

For Apache (.htaccess):

<FilesMatch "\.(vtt)$">
  Header set Access-Control-Allow-Origin "*"
</FilesMatch>

For Nginx:

location ~* \.(vtt)$ {
  add_header Access-Control-Allow-Origin *;
}

For CDN: Check your CDN’s CORS settings and enable cross-origin access.

See How to fix CORS errors for VTT subtitles for detailed instructions.

6. Confirm the caption track configuration

Check your JW Player setup code.

Correct configuration:

jwplayer("myPlayer").setup({
  file: "video.mp4",
  tracks: [{
    file: "https://example.com/captions.vtt",
    label: "English",
    kind: "captions",
    "default": true
  }]
});

Key properties:

  • file - Full URL to the VTT file (can be relative or absolute)
  • label - Display name in the caption menu (e.g., “English”, “Español”)
  • kind - Use "captions" or "subtitles"
  • "default" - Set to true to enable captions automatically

Multiple languages:

tracks: [
  {
    file: "captions.en.vtt",
    label: "English",
    kind: "captions",
    "default": true
  },
  {
    file: "captions.es.vtt",
    label: "Español",
    kind: "captions"
  }
]

7. Test captions in the embedded player

After configuration, test the player.

Steps:

  1. Load the page with the JW Player
  2. Click the CC (closed captions) button
  3. Verify your caption track appears in the menu
  4. Select it and confirm captions display
  5. Check timing matches the video

If captions don’t appear in the menu:

  • The tracks array might be empty or malformed
  • Check the browser console for JavaScript errors
  • Verify the JW Player version supports captions (v7+)

If captions appear but don’t display:

  • The VTT file might have syntax errors
  • Re-validate the file
  • Check that timestamps match your video duration

Common mistakes

Uploading SRT where VTT is expected

Problem: You renamed captions.srt to captions.vtt without converting the format.

Why this fails:

  • SRT uses commas for milliseconds: 00:00:01,000
  • VTT uses dots: 00:00:01.000
  • SRT doesn’t have the WEBVTT header
  • JW Player expects valid WebVTT and will reject SRT

Solution: Always convert SRT to VTT using the JW Player Subtitle Converter. Don’t just rename the file.

Hosting captions on a blocked domain

Problem: Your captions are on a CDN or different domain, and CORS blocks the request.

Symptom:

  • Video plays fine
  • Captions don’t show
  • Console shows CORS error

Why this happens: Browser security prevents loading resources from different origins unless the server explicitly allows it with CORS headers.

Solution:

  1. Add Access-Control-Allow-Origin: * header to your caption file server
  2. Or move the VTT file to the same domain as your player page
  3. Or use a CDN that supports CORS (most modern CDNs do)

Testing only the media file

Problem: You verify the video loads but don’t check if the caption file loads separately.

Why this matters: The video and captions are separate HTTP requests. The video can load successfully while the caption file fails with a 404 or CORS error.

Solution: Always check the Network tab in DevTools and specifically look for the VTT file request. Verify it returns 200 OK.

Using relative paths incorrectly

Problem:

tracks: [{
  file: "captions.vtt"  // Works locally, breaks in production
}]

Why this fails: Relative paths resolve differently depending on the page URL. What works on localhost might break on example.com/videos/page1/.

Solution: Use absolute URLs or root-relative paths:

tracks: [{
  file: "https://cdn.example.com/captions.vtt"  // Absolute URL
}]
// or
tracks: [{
  file: "/assets/captions.vtt"  // Root-relative path
}]

Forgetting the “default” property

Problem: Captions are configured but don’t show automatically.

Why this happens: Without "default": true, users must manually enable captions from the CC menu.

Solution: Set one track as default:

tracks: [{
  file: "captions.vtt",
  label: "English",
  kind: "captions",
  "default": true  // Enables captions automatically
}]

Wrong JW Player version

Problem: Using an old JW Player version that doesn’t support captions properly.

Solution: JW Player 7+ has full caption support. If you’re on v6 or earlier, upgrade to the latest version.

Check your version:

console.log(jwplayer.version);

Troubleshooting specific scenarios

Scenario 1: Captions work locally but not in production

Diagnosis:

  1. Check if the VTT file was uploaded to production
  2. Verify the production URL is correct
  3. Check CORS headers on the production server

Common cause: File path works locally but breaks after deployment because the directory structure changed.

Fix: Use absolute URLs in production or verify the relative path matches your production structure.

Scenario 2: Only some captions show

Diagnosis: Validate the VTT file and look for syntax errors.

Common cause: A malformed timestamp or missing blank line causes the parser to stop mid-file.

Fix:

  1. Run the file through the WebVTT Validator
  2. Fix reported errors
  3. Re-upload and test

Scenario 3: CC button is missing

Diagnosis: Check if the tracks array is empty or missing.

Common cause: JavaScript error preventing the player from initializing with captions.

Fix:

  1. Open browser console and look for errors
  2. Verify the tracks array is properly formatted
  3. Check that the JW Player script loaded successfully

Scenario 4: Captions show but timing is wrong

Diagnosis: The VTT file might be for a different video version.

Common cause: Video was edited (trimmed, scenes removed) but subtitles weren’t updated.

Fix: Use the Subtitle Time Shifter or Partial Subtitle Shifter to adjust timing.

Frequently asked questions

Does JW Player support SRT files?

JW Player officially supports WebVTT. While some versions may parse SRT, it’s not guaranteed to work. Always convert SRT to VTT for reliable playback.

Can I style JW Player captions?

Yes, JW Player supports custom caption styling through CSS and player configuration. However, styling must be done carefully to avoid breaking caption display.

Do I need a JW Player license for captions?

Caption support is available in both free and paid JW Player versions. However, the free version shows JW Player branding.

Can I use multiple caption languages?

Yes, add multiple objects to the tracks array, one per language. Users can switch languages from the CC menu.

Why do captions work in Chrome but not Safari?

Different browsers have slightly different WebVTT parsers. A file that’s technically invalid might work in Chrome but fail in Safari. Always validate your VTT files to ensure cross-browser compatibility.

Use the JW Player Subtitle Converter

Convert SRT or ASS subtitles to WebVTT captions for JW Player and browser-based video delivery. No signup, no upload, and everything runs locally in the browser.

Open JW Player converter