Before Embedding a Generated Song, Add a WebVTT Lyric File
On a fictional café website, the homepage song includes this line:
Meet me by the light.
The caption below the player says:
Meet me by the late.
One wrong word turns a warm lyric into nonsense. Anyone browsing with the sound muted sees only the mistake.
The audio draft may come from Suno v6 or another music tool. Once it leaves that workspace, keep a reviewed lyric file beside it.
Add Timings With WebVTT
WebVTT is a plain-text format for timed captions. Each block contains a start time, an end time, and the words to show.
WEBVTT
00:00:00.000 --> 00:00:04.200
Rain on the window, cups in a row
00:00:04.200 --> 00:00:08.600
Meet me by the light
00:00:08.600 --> 00:00:13.000
We will take the long way home
Save it with a language code:
cafe-evening.en.vtt
Create a separate file for each translation. Reusing the English timings without listening again may leave longer translated lines out of sync.
Connect It to the Player
Add the WebVTT file beside the audio source:
<audio
id="song"
controls
preload="metadata"
crossorigin="anonymous">
<source src="/audio/cafe-evening.mp3" type="audio/mpeg">
<track
id="lyrics-track"
kind="captions"
src="/lyrics/cafe-evening.en.vtt"
srclang="en"
label="English">
</audio>
<p id="current-lyric"></p>
<a href="/lyrics/cafe-evening.en.txt">
Read the full lyrics
</a>
Audio-only players do not always display caption tracks clearly. A small script can show the active line:
const trackElement = document.querySelector("#lyrics-track");
const lyricBox = document.querySelector("#current-lyric");
trackElement.addEventListener("load", () => {
const track = trackElement.track;
const showCurrentLine = () => {
const cue = track.activeCues?.[0];
lyricBox.textContent = cue ? cue.text : "";
};
track.addEventListener("cuechange", showCurrentLine);
showCurrentLine();
});
// Hidden mode loads the cues without drawing native captions.
trackElement.track.mode = "hidden";
Serve the file with the text/vtt MIME type. If the audio or caption file comes from another domain, that server must allow the request through CORS. The crossorigin attribute alone cannot grant access.
Keep a complete text version below or beside the player. A changing lyric line alone does not cover every accessibility need.

Keep Matching Versions Together
Store the checked lyrics separately from the audio and use the same version number:
audio/
cafe-evening-v3.mp3
lyrics/
cafe-evening-v3.en.vtt
cafe-evening-v3.en.txt
A short status file can show whether the pair is ready:
audio: cafe-evening-v3.mp3
lyrics: cafe-evening-v3.en.vtt
status: staging_only
checked:
wording: pass
timing: pass
mobile_player: pass
publication_rights: review_required
staging_only means the files may be tested on the website but are not yet cleared for public use.
Recheck Every Edited Line
Suppose the lyric changes to:
Wait for me beneath the light.
It may start at the same time but finish later. The following caption could now appear too early.
Start playback a few seconds before the edit, check the new line, and continue through the next two or three cues. Then test the result in the real player.
Also try pausing, skipping forward, muting the audio, and opening the page on a phone. The song should remain playable if the lyric file fails to load.
Check the Material Before Publishing
Before release:
- Review names, dates, prices, foreign words, and repeated choruses manually.
- Upload only lyrics, recordings, and references you are allowed to process.
- Do not imitate a recognizable singer or closely reproduce a protected song.
- Check whether the relevant account and terms cover the intended use.
- Record the audio source, edits, and approval status.
A downloadable song should not automatically be treated as exclusive or cleared for every commercial use.
A WebVTT file will not solve every accessibility or licensing question. It does make wrong words easier to catch and future edits easier to maintain—before “light” becomes “late” on the live page.
All rights reserved