Digital Signage Custom Apps

A custom app is a complete, self-contained website that you package as a .zip file and play on your screens like any other media. Everything is stored on the device, so the app keeps playing when the internet drops.

The player passes every custom app a set of player attributes: the identity and context of the screen it is running on, such as the player ID, the screen name, the resolution, the location and your tags. Your app reads those values and changes what it shows, so one package behaves differently on every screen. The attributes use Broadsign-compatible key names, so a creative moved from Broadsign can keep its field names.

With custom apps you can:

  • Show the right content per screen, store, zone, floor, region or language
  • Personalise data requests using the screen’s ID or tags
  • Keep playing offline
  • Reuse one package on hundreds of screens

 


 

Download the Sample

To see how custom apps work, upload the sample. It shows every attribute the screen sends, live on the screen.

Ready-made custom app sample

Download custom-app-sample.zip

The .zip contains three files:

FileWhat it is
index.htmlThe page itself, and always the entry point.
player.jsThe small reader you copy into your own app to get the player attributes.
demo.jsDraws the values on screen for the sample only. Leave it out of your own app.

The sample app on a screen

Required: the entry point of every custom app must be named index.html and sit at the top level of the .zip. Keep every image, style sheet, script and font inside the package and refer to them with relative paths, so the app works without an internet connection.

 


 

Quick Start Without Coding

  1. Upload the .zip in one of two ways:
    • In a playlist: open the playlist, click the layer, click Add New > Upload media, and choose the .zip. It is added to the layer straight away. See Upload Media.
    • In Media Assets: go to Media Assets, click Add Media > Upload Media Assets, and choose the .zip. Then add it to a playlist with Add New > Media Assets. See Media Assets.
  2. Click Publish changes of this playlist, and assign the playlist to a screen.

Upload Media Assets in Media Assets

The app appears in the layer. In the CMS the preview shows Preview mode with no values, because only a screen sends its attributes.

The sample custom app in a playlist layer

The sample appears on the screen and lists every attribute the screen sent. The green Connected banner confirms that it works.

 

Give Each Screen Its Tags

Apps that show different content per screen read the screen’s tags. Add tags as key:value, for example zone:north or menu:lunch: open the screen, click More > Tags, type each tag and press Enter, then click Save. See Screens.

Adding key:value tags to a screen

Only tags written as key:value reach your app as named values (tags.zone). A tag without a colon, such as lobby, is only included in tags.all.

 


 

How the Data Reaches Your App

Every time the app plays, the player adds the attributes to the app’s address as a query string:

index.html?player_id=PL-abc123&name=Main%20Lobby&display_unit_id=PL-abc123&resolution=1920x1080&tags.zone=north

The query string is always there, on every player, even if your page uses a strict Content-Security-Policy. Keys that start with tags. (for example tags.zone) are the screen’s tags.

 


 

For Developers: Read the Attributes

Copy player.js from the sample into your app and load it with a plain script tag before your own code:

<!-- index.html -->
<script src="player.js"></script>
<script>
  var screen = Player.read();     // the attributes, with the tags as an object

  var playerId = screen.player_id || "";
  var name     = screen.name || "";
  var zone     = screen.tags.zone || "";

  // ...use these values to drive your app.
</script>

Player.read() reads the query string and rebuilds the tags. keys into a tags object.

Load player.js as a classic script (<script src="...">), not as type="module". A classic external script also runs under a strict Content-Security-Policy (script-src 'self'), and it works on older Tizen, webOS and BrightSign players.

 

Moving from Broadsign? The attributes include the Broadsign key names (display_unit_id, display_unit_resolution, frame_resolution, campaign_id, display_unit_lat_long), so your field names carry over:

var screen = Player.read();
this.playerId = screen.player_id || "";
this.screenId = screen.display_unit_id || "";
this.latLong  = screen.display_unit_lat_long || "";

window.BroadSignObject is not available. Read the attributes with player.js instead.

 


 

Available Attributes

Each value is sent under its own name and its Broadsign name, so an app written for either can keep its field names.

AttributeBroadsign nameDescription
player_idplayer_idUnique player ID.
name—Name of the screen.
screen_iddisplay_unit_idScreen ID.
resolutiondisplay_unit_resolution, frame_resolutionScreen resolution, for example 1920x1080.
playlist_idcampaign_idID of the playlist the app is playing in.
—display_unit_lat_longScreen location as one "lat,long" string. Sent only when the location is known.
tags.<key>—Your key:value tags, for example tags.zone=north. tags.all lists them all.

Data minimisation: custom apps are third-party code, so only the attributes in this table are sent. Device identifiers (serial, device ID), the operating system, manufacturer and version details, separate coordinates, orientation, and playlist and media names are not passed to your app.

 

Tags

Tags are the key:value labels you add to your screens, for example zone:north, store:42 or lang:ar. Use them to drive your own logic:

var screen = Player.read();

screen.tags.zone;   // "north"
screen.tags.store;  // "42"
screen.tags.all;    // "zone:north,store:42"

Tags are case-sensitive; use lowercase keys. Up to 20 tags are sent to the device.

 


 

Value Rules

  • Every value is a string.
  • Unknown values are sent as an empty string "", except display_unit_lat_long, which is sent only when the location is known.
  • tags is always an object, possibly empty.
  • Keep the package self-contained and use relative paths so it runs fully offline.

 


 

Example: Show Different Content per Screen

<script src="player.js"></script>
<script>
  var screen = Player.read();
  var zone   = screen.tags.zone || "default";

  // pick content based on the screen's zone tag
  var banners = {
    north: "north-promo.jpg",
    south: "south-promo.jpg",
    default: "generic-promo.jpg",
  };
  document.getElementById("hero").src = banners[zone] || banners.default;

  // switch to a portrait layout on portrait screens (resolution is "WIDTHxHEIGHT")
  var res = (screen.resolution || "").split("x");
  if (res.length === 2 && Number(res[1]) > Number(res[0])) {
    document.body.classList.add("portrait");
  }
</script>

 


 

Troubleshooting

  • Nothing shows up: check that the entry file is named index.html, that it is at the top level of the .zip, and that every file uses a relative path.
  • A tag doesn’t work: upload the sample to the screen to see every value it sends. Tag names are case-sensitive, and only key:value tags arrive as named values.
  • The app fails on older players: keep your scripts as classic scripts, without type="module", so they run on older Tizen, webOS and BrightSign players.
  • Test before you upload: open index.html in a browser with test values added to the address, for example index.html?player_id=TEST&name=Lobby&resolution=1080x1920&tags.zone=north, to see how your app reacts.