Edge Apps

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.

Getting Started

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

Create an 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 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:

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.

Playground Edge Apps

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.

Deploy the Edge App

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.

Instances

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

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.

Instance Manifest

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.

Instance Manifest Reference

Syntax

The syntax field specifies the version of the instance manifest file. The current version is instance_v1.

ID

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.

Name

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.

Entrypoint URI

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.

Manifest File

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:

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.

Reference

Syntax

The syntax field specifies the version of the manifest file. The current version is manifest_v1.

ID

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.

Entrypoint

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 the index.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.

Description

The description field provides a brief overview of the Edge App, which will be visible in the Screenly web dashboard.

Icon

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.

Author

The author field specifies the name of the Edge App's creator.

Homepage URL

The homepage_url field is a URL directing to the homepage of the Edge App.

Auth

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.

Ready Signal

The ready_signal field is an optional boolean parameter in the Edge App configuration.

Purpose

When set to true, it enables a mechanism for the Edge App to control when it gets rendered on the Screenly Player.

Use Case

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.

Implementation

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.

Important Notes
  1. If ready_signal is true and the function is never called, the content will not be displayed.
  2. Once the function has been called successfully, any subsequent calls will be ignored.
  3. If ready_signal is false, the content will be displayed as soon as possible, and any calls to screenly.signalReadyForRendering() will have no effect.

Settings

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.

Settings

Defining a Setting

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

Setting a Setting

Modify the Greeting

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!".

Getting Settings

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 |
+----------+-------------+---------------+----------+--------+-----------------------------------------------------------+

Using Settings in Your Edge App

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

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

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

Reserved setting names

Settings starting with screenly_ are reserved and cannot be used in the manifest file.

Global Branding Settings

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:

Branding Settings List

screenly_color_accent

This is the accent color of the customer's brand.

Setting Example Value
screenly_color_accent #7E2CD2

screenly_color_light

The lighter color of the brand. This color should be used on a dark background.

Setting Example Value
screenly_color_light #454BD2

screenly_color_dark

The darker color of the brand. This color should be used on a light background.

Setting Example Value
screenly_color_dark #000212

screenly_logo_light

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

screenly_color_dark

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

Notes on Branding Settings

These settings are available to the Edge App like the usual settings but cannot be listed, fetched, or changed with CLI.

Security Model

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.

Transmission and Storage Security

Secrets ensure that sensitive data is securely managed and transmitted, providing robust security for your applications.

Metadata

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:

Edge App emulator

After creating your Edge App, you can use the Edge App emulator to test it in your web browser.

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.

Debugging

Coming soon.

Cross-Origin Resource Sharing (CORS)

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

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).

Gotchas

Runtime Environment

Security is at the core of Edge Apps, and several measures have been implemented to ensure their security.

Browser Sandboxing

Edge Apps run inside the browser within appropriate security profiles, ensuring a sandboxed environment.

Isolated Runtime 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.