Building a Station Website with TD Widgets
This guide walks through embedding Triton Digital widgets into a station website — from a single player to a full layout with ad zones, song history, and preroll monetization.
Prerequisites
Before you start you need:
- Your station callsign (e.g.
TRITONRADIOMUSIC) or mount point — get this from your Triton account manager - Your brand hex colors (primary, secondary, highlight)
- A square cover-art fallback image hosted at a public URL
- For ad monetization: a VAST tag URL or TAP station ID
1. Include the Widget Script
Add one <script> tag near the bottom of <body>. Everything else is driven by custom HTML elements — no additional JavaScript is required to render widgets.
<script src="//widgets.listenlive.co/1.0/tdwidgets.min.js"></script>
To change the interface language, add td-lang to the script tag (supported values: en, es, pt, fr):
<script src="//widgets.listenlive.co/1.0/tdwidgets.min.js" td-lang="es"></script>
2. Add a Player
Place a <td-player> element anywhere in the page. The station attribute is the only required field beyond id.
<td-player
id="td-player"
type="classic"
station="YOUR_STATION_CALLSIGN"
defaultcoverart="https://yourstation.com/cover-art.jpg"
primarycolor="#ffffff"
secondarycolor="#222222"
highlightcolor="#e63946"
autostart="false">
</td-player>
Choosing a Layout
type |
Best for | Minimum width |
|---|---|---|
bar |
Sticky header/footer bar spanning the full page width | any |
classic |
Sidebar or centered content block | ~500 px |
mini |
Tight sidebar or mobile-first layouts | 150 px |
vertical |
Square hero block or standalone widget | 300 px |
timeshift |
Stations that offer on-demand/catch-up streams | ~500 px |
Key Player Attributes
| Attribute | Example | Notes |
|---|---|---|
station |
TRITONRADIOMUSIC |
Station callsign — use this or mount, not both |
mount |
MOUNT_NAME |
Mount point alternative to station |
defaultcoverart |
https://…/art.jpg |
Shown when no track artwork is available |
primarycolor |
#ffffff |
Text and controls |
secondarycolor |
#222222 |
Background and panels |
highlightcolor |
#e63946 |
Hover and active states |
autostart |
false |
Set to true to begin streaming on page load |
defaultvolume |
0.5 |
0–1 range; defaults to 0.3 |
leaderboard |
"ad-leaderboard" |
ID of a 728×90 companion ad div |
mediumrectangle |
"ad-medium-rect" |
ID of a 300×250 companion ad div |
buybtnvisible |
false |
Hide the iTunes/buy button |
coverartvisible |
true |
Show/hide album art |
streamwhilemuted |
true |
Keep stream alive when volume is 0 |
3. Set Up Ad Banner Zones
Companion banners are standard IAB ad containers. Declare them as empty <div> elements and reference their id from the player. During an ad break the widget fills them with ad creative; outside of ad breaks you can put static fallback content inside them.
<!-- 728×90 leaderboard — place above or below the player -->
<div id="ad-leaderboard" style="width:728px; height:90px;">
<img src="https://yourstation.com/ads/default-leaderboard.jpg"
alt="Advertisement" style="width:100%; height:100%;">
</div>
<!-- 300×250 medium rectangle — place in a sidebar -->
<div id="ad-medium-rect" style="width:300px; height:250px;">
<img src="https://yourstation.com/ads/default-medium-rect.jpg"
alt="Advertisement" style="width:100%; height:100%;">
</div>
<td-player
id="td-player"
type="classic"
station="YOUR_STATION_CALLSIGN"
leaderboard="ad-leaderboard"
mediumrectangle="ad-medium-rect"
…>
</td-player>
The static images act as house ads or sponsorship banners when no programmatic ad is active. The widget replaces them automatically during ad breaks and restores the container afterward.
4. Add Song History
Link <td-songhistory> to the player with playerlink so the history list updates automatically whenever the station is changed via the player's trigger('play', …) method.
<td-songhistory
id="td-songhistory"
station="YOUR_STATION_CALLSIGN"
playerlink="td-player"
songsdisplayed="10"
title="Recently Played"
buybtntext="Buy"
primarycolor="#ffffff"
secondarycolor="#f0f0f0"
headerbgcolor="#222222"
highlightcolor="#e63946"
timeplayedvisible="true">
</td-songhistory>
Song History Attributes
| Attribute | Notes |
|---|---|
playerlink |
id of a td-player element — keeps history in sync when station changes |
songsdisplayed |
Number of tracks to show |
timeplayedvisible |
Show the time each track was played |
buybtnvisible |
Show/hide the buy link per track |
thirdpartylookup |
Enable iTunes metadata lookups (default true) |
5. Add Preroll Ads
<td-adplayer> handles video and audio prerolls. There are three display modes:
Theater mode (fullscreen overlay)
The ad covers the entire viewport. No additional container is needed — this is the default.
<td-adplayer
id="td-adplayer"
client="tap"
host="cmod-world.live.streamtheworld.com"
stationid="YOUR_TAP_STATION_ID"
type="preroll"
onappready="adReady"
onadcomplete="adComplete">
</td-adplayer>
Embedded mode (ad renders inside a container)
<div id="ad-container" style="width:640px; height:360px; position:relative;">
<!-- fallback content shown before/after the ad -->
<img src="https://yourstation.com/ads/preroll-fallback.jpg"
alt="Advertisement" style="width:100%; height:100%;">
</div>
<td-adplayer
id="td-adplayer"
client="vast"
tag="https://your-ad-server.com/vast-tag.xml"
mode="embedded"
tdcontainer="ad-container"
mediumrectangle="ad-medium-rect"
leaderboard="ad-leaderboard"
onappready="adReady"
onadcomplete="adComplete">
</td-adplayer>
Note: The
tdcontainerelement must haveposition: relativein its CSS.
In-player mode (ad renders inside the player widget)
<td-adplayer
id="td-adplayer"
client="vast"
tag="https://your-ad-server.com/vast-tag.xml"
mode="player"
playerid="td-player">
</td-adplayer>
Triggering the preroll before playback
Wire up the onadcomplete callback to start the stream after the ad finishes. Call trigger('playAd') when the user clicks play.
<td-player
id="td-player"
type="classic"
station="YOUR_STATION_CALLSIGN"
autostart="false"
onappready="playerReady">
</td-player>
<td-adplayer
id="td-adplayer"
client="tap"
host="cmod-world.live.streamtheworld.com"
stationid="YOUR_TAP_STATION_ID"
type="preroll"
onappready="adReady"
onadcomplete="adComplete">
</td-adplayer>
<script>
var player, adWidget, adPlayed = false;
function playerReady(w) { player = w; }
function adReady(w) { adWidget = w; }
function adComplete() {
player.trigger('play', { station: 'YOUR_STATION_CALLSIGN' });
}
// Call this from a custom play button instead of relying on the widget's own button
function onPlayClick() {
if (!adPlayed && adWidget) {
adWidget.trigger('playAd');
adPlayed = true;
} else if (player) {
player.trigger('play', { station: 'YOUR_STATION_CALLSIGN' });
}
}
</script>
6. Dynamic Station Switching
Use trigger('play', …) to switch stations without reloading the page. Update the song history by also changing its station attribute, or use playerlink to keep them in sync automatically.
function switchStation(callsign) {
player.trigger('play', { station: callsign });
}
7. Full Page Layout Example
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Station</title>
<style>
body { margin:0; font-family: sans-serif; background:#111; color:#fff; }
/* sticky bar player */
#player-bar { position:fixed; bottom:0; left:0; right:0; z-index:100; }
/* main layout */
.page { display:flex; gap:24px; padding:24px 24px 80px; max-width:1200px; margin:0 auto; }
.main { flex:1; min-width:0; }
.aside { width:336px; flex-shrink:0; }
/* ad containers */
#ad-leaderboard { width:728px; max-width:100%; height:90px; margin:0 auto 24px; }
#ad-medium-rect { width:300px; height:250px; margin-bottom:24px; }
</style>
</head>
<body>
<!-- Leaderboard banner (728×90) above content -->
<div id="ad-leaderboard">
<img src="https://yourstation.com/ads/leaderboard.jpg"
alt="Advertisement" style="width:100%;height:100%;">
</div>
<div class="page">
<!-- Main content -->
<div class="main">
<h1>Welcome to My Station</h1>
<p>Your station tagline or description goes here.</p>
<td-songhistory
id="td-songhistory"
station="YOUR_STATION_CALLSIGN"
playerlink="td-player"
songsdisplayed="10"
title="Recently Played"
buybtntext="Buy"
primarycolor="#ffffff"
secondarycolor="#1a1a1a"
headerbgcolor="#222222"
highlightcolor="#e63946"
timeplayedvisible="true">
</td-songhistory>
</div>
<!-- Sidebar -->
<aside class="aside">
<!-- 300×250 medium rectangle -->
<div id="ad-medium-rect">
<img src="https://yourstation.com/ads/medium-rect.jpg"
alt="Advertisement" style="width:100%;height:100%;">
</div>
<p>Sidebar content — schedule, social links, etc.</p>
</aside>
</div>
<!-- Sticky bar player at the bottom -->
<div id="player-bar">
<td-player
id="td-player"
type="bar"
station="YOUR_STATION_CALLSIGN"
defaultcoverart="https://yourstation.com/cover-art.jpg"
primarycolor="#ffffff"
secondarycolor="#111111"
highlightcolor="#e63946"
autostart="false"
leaderboard="ad-leaderboard"
mediumrectangle="ad-medium-rect">
</td-player>
</div>
<!-- Preroll (theater/fullscreen) — plays before stream on first click -->
<td-adplayer
id="td-adplayer"
client="tap"
host="cmod-world.live.streamtheworld.com"
stationid="YOUR_TAP_STATION_ID"
type="preroll">
</td-adplayer>
<script src="//widgets.listenlive.co/1.0/tdwidgets.min.js"></script>
</body>
</html>
Demo Pages
Some demo are available here:
| Demo | Description |
|---|---|
| Station design | Complete station page — bar player, song history, leaderboard + medium rectangle static banners |
| Card design | Single-card microsite — hero image, bar player with a leaderboard companion banner, and song history, all in one themed panel |
| Fullscreen design | Vertical player with theater-mode (fullscreen) preroll before the stream starts |
| Classic design with banners | Classic player with all companion banner slots and static fallback images |
Tips
- Colors — use your station's exact brand hex values. The widget inherits no styles from the parent page; every color is set explicitly.
- Cover art — host a square image (at least 200×200 px) on a CDN. The default Triton art is a fallback, not a brand asset.
- Ad blocker handling — listen to
onadblockerdetectedon<td-adplayer>and show a friendly message rather than silently failing. - Multiple stations on one page — give each widget a unique
idand usetrigger('play', { station: '…' })to switch without reloading. - Mobile — the
barlayout scales gracefully to narrow viewports. For full-page embeds on mobile, theminiorverticallayouts work better thanclassic.