Edge Apps is a framework for building and running content for your digital signage screens. Inspired by Serverless movement, Edge Apps enables you to build sophisticated digital signage content without the need for running your own infrastructure.
If you're familiar with Heroku, Cloudflare Workers, or any similar technology, you'll feel right at home with Edge Apps.
Here's a content section for the document:
- Getting Started
- Manifest File
- Global Branding Settings
- Security Model
- Metadata
- Edge App Emulator
- Debugging
- Cross-Origin Resource Sharing (CORS)
- Monitoring
- Gotchas
- Runtime Environment
- Browser Sandboxing
- Isolated Runtime Environment
First, you need to install the Screenly CLI. The CLI is used to both generate and upload Edge Apps.
With the CLI installed and logged in (screenly login
), we can create our "Hello World" example.
To do this, first create a new directory where the Edge App will reside. For production applications, this would likely be a source-controlled folder (e.g., git
), but for now, let's create a temporary folder with:
$ mkdir -p ~/tmp/edge-app
$ cd ~/tmp/edge-app
To create an Edge App, simply run:
$ screenly edge-app create --name hello-world
When you run the screenly edge-app create command, two files will be created in the current directory:
screenly.yml
index.html
screenly.yml
contains the metadata. In this file, you can define settings, secrets, and various other metadata. In our "Hello World" example, we have a single setting called greeting
, which is used in the Edge App.
index.html
is our entry point. It is what the client (i.e., the player) will load. This particular file is very simple and just includes some styling and various metadata examples.
Once you have initiated your Edge App, you can start adding content. We make a few assumptions about your Edge App:
- No files below the current can be references (just like you can't use the
COPY
in aDockerfile
outside the current working directory) - The following file names are reserved by the system:
screenly.yml
- Reserved for the manifest file.screenly.js
- Reserved for on-device usage to interact with the system.
Other than that, you can develop your Edge App just like you would do with a regular static HTML site. You can break out JavaScript, CSS, images, etc., into separate files and include them as you normally would.
Getting started with our existing Playground Edge Apps can help ease your introduction to Edge Apps development. To test your skills, first clone our Playground GitHub Repository (https://github.com/Screenly/Playground). After cloning, navigate to one of the example Playground Edge App folders and execute the following command:
For instance, if our target is the Clock App, enter the directory (Playground/edge-apps/clock
) and execute:
$ screenly edge-app create --name "My Groundbreaking Clock App" --in-place
Note the --in-place
parameter. This is necessary when creating an app with existing screenly.yml
and index.html
files, as our Playground Edge Apps do. Otherwise, you'll encounter errors about conflicting files. This parameter is not mandatory if you are creating a brand new Edge App; it’s just here to make your developer life a little bit easier.
To deploy an Edge App, use the following command:
$ screenly edge-app deploy
The deployment process includes the following steps:
Upload: The Edge App is uploaded to the server.
Replacement: If the Edge App has been previously uploaded, the existing files are replaced with the new ones.
Sync Settings: The deployment synchronizes the settings from the manifest file with the server.
Automatic Update: All instances of the Edge App will automatically update to the latest deployed version, ensuring consistency across all devices.
An instance is a unique installation of an Edge App. Each instance can have its own settings and secrets, allowing you to run multiple instances of the same Edge App with different configurations. While the CLI currently supports managing a single instance via the instance.yml
file, the Screenly Web Dashboard can manage multiple instances simultaneously.
Each instance produces an asset that can be scheduled on a screen. This is the only method for scheduling an Edge App on a screen.
To manage instances, you can use the following commands:
$ screenly edge-app instance list
$ screenly edge-app instance create
$ screenly edge-app instance update
$ screenly edge-app instance delete
-
Create: The
create
command generates a new instance and creates aninstance.yml
file in the current directory. -
List: The
list
command displays all instances associated with your account. -
Update: The
update
command modifies an existing instance based on the changes made in theinstance.yml
file. -
Delete: The
delete
command removes an instance from your account.
After creating an instance, navigate to your Screenly web console. You should see the new instance of your Edge App listed in the content section, where you can schedule it as you would with a regular asset.
The instance.yml
file is used to manage the instance of an Edge App. Currently, the CLI supports managing only one instance at a time.
The syntax
field specifies the version of the instance manifest file. The current version is instance_v1
.
The id
field is a unique identifier for the instance. This ID is generated by the system and is used to identify the instance across the platform.
The name
field specifies the name of the instance. It can be updated by modifying the value in the instance.yml
file and executing the screenly edge-app instance update
command.
The entrypoint_uri
field specifies the entry point for the Edge App. This field is only required when the Edge App entry point is a remote URL. It can be updated by modifying the value in the instance.yml
file and executing the screenly edge-app instance update
command.
The manifest file defines various properties of an Edge App and is loosely inspired by the Chrome extension manifest file, but uses YAML (specifically StrictYAML).
When you create a new Edge App using the CLI (screenly edge-app create --name <APP NAME>
), a manifest file named screenly.yaml
is automatically created in the current directory.
Manifest Reference
syntax: manifest_v1
id: 01H7DD8SV32F9FKWXXXXXXXXXX
entrypoint:
type: file
description: 'Displays the current weather and time'
icon: 'https://example.com/some-logo.svg'
author: 'Screenly, Inc'
homepage_url: 'https://www.screenly.io'
settings:
google_maps_api_key:
type: secret
title: API Key
optional: false
help_text: Specify a commercial Google Maps API key. Required due to the app's map feature.
greeting:
type: string
default_value: "Cowboy Neil"
title: greeting
optional: true
help_text: An example of a string setting that is used in index.html
Edge Apps can have settings, which are key-value pairs that users installing the app must provide at install time and can later edit. The values in these settings are exposed to the app via environment variables or secrets. There are two types of settings:
- String
- Secret
Each setting may have a default value, an optional flag indicating if it's required, a human-readable title, and help text to assist users in configuring the app.
The syntax
field specifies the version of the manifest file. The current version is manifest_v1
.
The id
field is a unique identifier for the Edge App. This ID is generated by the system and is used to identify the Edge App across the platform.
The entrypoint
field specifies the entry point for the Edge App. It is optional and defaults to the file type. The entrypoint
field contains the following subfields:
- type: Defines the type of entry point. Possible values are:
file
: The entry point is theindex.html
file in the Edge App directory.remote-global
: The entry point is a URL that is consistent across all instances of the Edge App.remote-local
: The entry point is a URL unique to each instance of the Edge App.
- uri: The URL of the entry point. This field is required if the type is
remote-global
.
The description
field provides a brief overview of the Edge App, which will be visible in the Screenly web dashboard.
The icon
field is a URL pointing to an image that represents the Edge App. This image will be displayed in the Screenly web dashboard.
The author
field specifies the name of the Edge App's creator.
The homepage_url
field is a URL directing to the homepage of the Edge App.
The auth
field is optional and is used to configure Edge App authentication. It includes the following subfields:
- auth_type: Specifies the type of authentication. Possible values are:
basic
: Basic authentication.bearer
: Bearer token authentication.
- global: A boolean value that determines whether the authentication is global (
true
) or local (false
).
For Basic authentication, the following settings are generated:
screenly_http_basic_auth_username
screenly_http_basic_auth_password
For Bearer authentication, the following setting is generated:
screenly_http_bearer_token
These settings must be configured using the screenly edge-app setting set
command.
The ready_signal
field is an optional boolean parameter in the Edge App configuration.
When set to true
, it enables a mechanism for the Edge App to control when it gets rendered on the Screenly Player.
This feature is particularly useful for apps that require initial loading or data preparation before they're ready to be shown. For example, an app might need to fetch data or complete some initialization process.
A practical example is our PowerBI Edge App, which uses this feature to delay showing the dashboard until all data is loaded and rendered. This ensures that users see a fully populated dashboard instead of a loading screen.
When the Edge App is prepared and ready to be displayed, it must call the screenly.signalReadyForRendering()
function. This signals to the Screenly Player that the app is now ready for rendering.
- If
ready_signal
istrue
and the function is never called, the content will not be displayed. - Once the function has been called successfully, any subsequent calls will be ignored.
- If
ready_signal
isfalse
, the content will be displayed as soon as possible, and any calls toscreenly.signalReadyForRendering()
will have no effect.
The settings
field is a dictionary of key-value pairs that define the configurable settings for the Edge App. For more details, refer to the Settings section.
To define a setting, you can use the following structure in your manifest file:
settings:
[...]
greeting:
type: string
default_value: "Cowboy Neil"
title: greeting
optional: true
help_text: An example of a string setting that is used in index.html
With the asset scheduled on your screen, you should see the headline "Hello Stranger!". This is actually a setting configured in screenly.yml
. You can override this using the edge-app setting
command to change it.
$ screenly edge-app setting set greeting='Cowboy Neil'
This will output:
Edge app setting successfully set.
It might take a few minutes for your screen to pick up the change, but once it does, the headline should change from "Hello Stranger!" to "Hello Cowboy Neil!".
To list the current settings, use the following command:
$ screenly edge-app setting list
This will output:
+----------+-------------+---------------+----------+--------+-----------------------------------------------------------+
| Title | Value | Default value | Optional | Type | Help text |
+----------+-------------+---------------+----------+--------+-----------------------------------------------------------+
| greeting | Cowboy John | Cowboy Neil | Yes | string | An example of a string setting that is used in index.html |
+----------+-------------+---------------+----------+--------+-----------------------------------------------------------+
To use the settings in your Edge App, include them in your HTML or JavaScript files as follows:
[...]
<head>
<script src="screenly.js?version=1"></script>
</head>
[...]
<script>
document.getElementById("greeting").innerText = screenly.settings.greeting;
</script>
[...]
Settings are key-value pairs that users installing the app must provide at install time and can later edit.
Global settings are secrets defined for the instances of an Edge App. These settings are shared across all instances of the app and are specified in the manifest file.
settings:
[...]
global_greeting:
type: string
default_value: "Cowboy Neil"
title: greeting
optional: true
help_text: An example of a string setting that is used in index.html
global: true
Secret settings are similar to regular settings but are used for sensitive data that should not be exposed to the user. These settings are stored securely and are not visible to the user. Secrets settings must not have a default_value.
settings:
[...]
api_key:
type: secret
title: API Key
optional: false
help_text: An example of an API key
Settings starting with screenly_
are reserved and cannot be used in the manifest file.
The Global Branding Settings feature automatically provides relevant visual identity information by fetching it from the public sources based on their email domain. This functionality is available by default for every Edge App, requiring no special actions from the developer to access the following settings:
- screenly_color_accent
- screenly_color_light
- screenly_color_dark
- screenly_logo_light
- screenly_logo_dark
This is the accent color of the customer's brand.
Setting | Example Value |
---|---|
screenly_color_accent | #7E2CD2 |
The lighter color of the brand. This color should be used on a dark background.
Setting | Example Value |
---|---|
screenly_color_light | #454BD2 |
The darker color of the brand. This color should be used on a light background.
Setting | Example Value |
---|---|
screenly_color_dark | #000212 |
The light version of the logo. A light logo should be displayed on a dark background.
Setting | Example Value |
---|---|
screenly_logo_light | screenly_logo_light |
The dark version of the logo. A dark logo should be displayed on a light background.
Setting | Example Value |
---|---|
screenly_dark_light | screenly_logo_light |
These settings are available to the Edge App like the usual settings but cannot be listed, fetched, or changed with CLI.
Screenly's secrets function similarly to settings but with enhanced security measures. They are write-only, meaning they cannot be retrieved via the API or web interface once written.
Secrets are defined in screenly.yml
, but their values are not set within the manifest file. Instead, they are securely managed through the Edge App.
-
Screenly Player Max: Each device has a unique pair of public/private keys stored in a Trusted Platform Module (TPM), allowing the use of x509 cryptography. Payloads sent to a Screenly Player are encrypted with the device's public key, ensuring only the intended device can decrypt it. Secrets are encrypted on disk using the TPM, making them inaccessible even if the hard drive is compromised.
-
Standard Screenly Player: While these devices do not have a TPM, they still use x509 cryptography with certificates securely stored on disk. This provides a high level of protection for stored secrets, even without hardware-level security.
Secrets ensure that sensitive data is securely managed and transmitted, providing robust security for your applications.
Sample Edge App Use
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Metadata</title>
<script src="screenly.js?version=1"></script>
</head>
<body >
<p>I'm <span id="screen-name"></span>.</p>
</body>
<script>
document.getElementById("screen-name").innerText = screenly.metadata.screen_name;
</script>
</html>
In many scenarios, you may need to utilize metadata within your Edge Apps. For example, you might want to develop a wayfinding app that shows the location of the screen and directs users to a specific destination.
Since each screen inherently possesses a wealth of information about itself, including its geographical location, we've made this data accessible within the Edge App framework.
This metadata includes:
- name: The human-readable name assigned to the screen.
- hostname: The unique hostname (which also serves as the identifier) assigned to the screen.
- coordinates: The latitude and longitude coordinates of the screen's location, which can be edited via the web interface.
- Returned as a dictionary.
- location: The human-readable location as displayed in the web interface.
- hardware: Details about the hardware of the device.
- version: The software version running on the Screenly device.
- tags: The tags or labels assigned to the screen.
- Returned as a dictionary.
After creating your Edge App, you can use the Edge App emulator to test it in your web browser.
- To do this, open your terminal and navigate to the Edge App directory.
- Run this command:
Run Edge App emulator
$ screenly edge-app run
This command will provide you with a URL to access your Edge App in your browser.
If you don't have sample data in your Edge App directory, you can create it by running this command:
Add mock data to run Edge App emulator
$ screenly edge-app run --generate-mock-data
After generating the mock data, run the Edge App emulator again to see your app in action.
Coming soon.
Cross-origin resource sharing is a mechanism that allows restricted resources on a web page to be accessed from another domain outside the domain from which the first resource was served. Some APIs, particularly public ones, use CORS to restrict access. Sometimes you need to bypass CORS. To do this, we provide you with a handy CORS proxy mitigation strategy.
The way it works is very straightforward. Instead of accessing the API directly from JavaScript, you access it via the CORS proxy. The CORS proxy removes the CORS policy so that you can circumvent the restriction.
For instance, if you're trying to access the API endpoint https://api.example.com/v1
, but it has a CORS policy preventing access, you can bypass this policy using the CORS proxy built into Edge Apps. Here's how you can modify your code to use the CORS proxy:
[...]
<head>
<script src="screenly.js?version=1"></script>
</head>
<body>
[...]
<script>
cost api_url = 'https://api.example.com/v1';
cost bypass_cors_url = screenly.cors_proxy_url + api_url;
</script>
[...]
</body>
In the example code snippet above, replace api_url
with bypass_cors_url
to interface with the API as usual through the CORS proxy.
Monitoring is in invite-only beta.
When developing Edge Apps, it's crucial to monitor the performance of the device running the app. This is especially important for low-powered devices, such as Raspberry Pis, where resources are limited.
To assist with monitoring, we have chosen Prometheus as the platform to expose metrics.
When monitoring is enabled, the device exposes Prometheus metrics at port 9100
, utilizing Node Exporter. This enables you to scrape metrics and visualize them using tools like Grafana, which can be integrated seamlessly with Screenly for visualization purposes (learn more about Grafana integration with Screenly).
- You need to use relative paths to assets (e.g., static/image.svg rather than absolute paths (e.g., /static/image.svg).
Security is at the core of Edge Apps, and several measures have been implemented to ensure their security.
Edge Apps run inside the browser within appropriate security profiles, ensuring a sandboxed environment.
The Edge App runtime environment itself is isolated, preventing Edge Apps from communicating or accessing files/data from another Edge App. This isolation extends not only to files and environment data (such as settings) but also to secrets.