Getting Started with Vega Web Apps: A Developer’s Playbook

With the launch of our new cutting-edge OS, we are thrilled to introduce React Native for Vega — a groundbreaking solution that allows you to build React Native apps for all of our supported devices. React Native for Vega doesn’t just unlock device functionalities, but also seamlessly integrates with Amazon’s suite of services to deliver an unparalleled customer experience. Our team is positively electric about sharing this transformative power with other technologies, and so we are overjoyed to announce the effortless integration of React Native for Vega with your very own web streaming applications!

Vega Web Apps leverage the Chromium web engine to enable web-based application development on the Vega platform. This component utilizes the Chromium engine to parse and render web content, allowing seamless integration and interaction with the encompassing React Native for Vega application. This engine employs a multiprocess architecture, running each web page in its own isolated process, enhancing the overall security and stability of the system. It’s designed to be fast, efficient, and highly customizable, so you can create complex and dynamic web applications.

This guide covers essential areas to focus on when developing Vega Web Apps. It will be essential to follow the React Native for Vega playbook for the React Native for Vega components. This guide will start you through creating a Vega Web App and following best practices to have a high quality, performant, and reliable customer experience.

Architecture & Understanding

A solid architectural foundation is key to building scalable and maintainable Vega apps:


Quick Start

  1. Install the Vega SDK
  2. Install Vega Studio
  3. Create a new app from template
  4. Install the Vega Web App library
npm install @amazon-devices/webview
  1. If the WebView component doesn’t exist, create one in App.tsx
  2. Update the source uri in the WebView to your web app’s address or to a local file
<WebView
    source={{
        // headers: {},
    
        // Replace with your URL.
        uri: 'https://example.com',
        // or to reference a file located at <root>/assets/index.html
        // uri: "file:///pkg/assets/index.html"
    }}
  1. Make sure your manifest file includes the correct entries to support the WebView component
schema-version = 1

[package]
title ="<App Name>"
version = "0.1.0"
id = "<package-id>"

[components]
[[components.interactive]]
id = "<package-id>.main"
categories = ["com.amazon.category.main"]
runtime-module = "/com.amazon.kepler.keplerscript.runtime.loader_2@IKeplerScript_2_0"
launch-type = "singleton"

[wants]

# Web renderer service for rendering web content
[[wants.service]]
id = "com.amazon.webview.renderer_service"

# If Web App needs keyboard support
[[wants.service]]
id = "com.amazon.inputmethod.service"

# If Web App needs video playback
[[wants.service]]
id = "com.amazon.media.server"

# Required for emitting metrics from video playback
[[wants.service]]
id = "com.amazon.mediametrics.service"

# Required for video playback on stable APIs
[[wants.service]]
id = "com.amazon.mediabuffer.service"
[[wants.service]]
id = "com.amazon.mediatransform.service"

# If Web App needs audio playback
[[wants.service]]
id = "com.amazon.audio.stream"

# Required for audio management features to work in WebView, features like audio focus, volume control 
[[wants.service]]
id = "com.amazon.audio.control"

# To enable accessibility support for your app, it's highly recommended you add UCC service with Service Registrar
[[wants.service]]
id = "com.amazon.kepler.ucc.publisher"

# Uncomment below section to enable encrypted media playback (DRM content)
# [[wants.service]]
# id = "com.amazon.drm.key"
# [[wants.service]]
# id = "com.amazon.drm.crypto"
# [[needs.privilege]]
# id = "com.amazon.privilege.security.file-sharing"

# Enable Group-IPC to access media services
[[wants.service]]
id = "com.amazon.gipc.uuid.*"
[offers]
[[offers.service]]
id = "com.amazon.gipc.uuid.*" 

# You may add other services as needed

:herb: Notable WebView Component Properties

Here are several WebView component properties that are recommended to use in your existing web application to support Fire TV devices. For a full list of API references, refer to React Native for Vega’s WebView Component Reference.

:leaf_fluttering_in_wind: allowSystemKeyEvents

Boolean property that determines whether the app would like to listen for special system key events like Back button(keyCode: 27) in their web JavaScript layer. This functionality helps developers who would like to keep their business logic fully on the website instead of relying on (React Native for Vega) application code.

allowSystemKeyEvents: true (recommended)

:light_bulb: Note: When this property is set to ‘true’, system key events will be delivered only in web javascript and not in application code (React Native for Vega). Also, only one WebView instance (most recent) will receive system key events even if there are multiple WebView instances on the screen.

:leaf_fluttering_in_wind: allowsDefaultMediaControl

Boolean value to enable/disable default Media Controls for WebView playback. When set to true, it activates Media Controls for the media session. When set to false, Media Controls are disabled. Note: These controls apply to all media content types, including advertisements and live streams.

allowsDefaultMediaControl: true (recommended, default is true)

:leaf_fluttering_in_wind: domStorageEnabled

Enables DOM storage (localStorage/etc) within the WebView.

domStorageEnabled: true (recommended)

:leaf_fluttering_in_wind: hasTVPreferredFocus

Must be set to true to force the TV focus engine to move focus to this view on launch. Otherwise, it will require manual input to load from the remote.

hasTVPreferredFocus: true (mandatory setting)

:leaf_fluttering_in_wind: javaScriptEnabled

Enables JavaScript within the WebView.

javaScriptEnabled: true (recommended)

:leaf_fluttering_in_wind: mediaPlaybackRequiresUserAction

Boolean that determines whether HTML5 audio and video requires the user to tap them before they start playing. The default value is true.

mediaPlaybackRequiresUserAction: false (recommendation)

// set this to false if you want the content to auto play when launched

:leaf_fluttering_in_wind: mixedContentMode

Specifies the mixed content mode. Sets the WebView’s behavior when a secure origin tries to load a resource from any other origin. Possible values for mixedContentMode are:

Parameter Description
'never' (default) WebView will not allow a secure origin to load content from an insecure origin.
'compatibility' WebView will attempt to be compatible with the approach of a modern web browser with regard to mixed content.
'always' WebView will allow a secure origin to load content from any other origin, even if that origin is insecure.
mixedContentMode: never|compatibility (depending on your Web App needs)

// we do not recommend setting this to 'always'

:notebook_with_decorative_cover: Notable Methods and Classes

onLoadStart(): invoked when WebView starts loading.
onLoad(): invoked after the WebView finishes loading.

onError(): invoked when WebView load fails.
onHttpError(): invoked when WebView encounters an http error.
onSslError(): invoked when WebView encounters an ssl/certificate error.

onMessage(): invoked when WebView calls ReactNativeWebView.postMessage(data: string).

CookieManager: is useful for the following:

  • CookieManager.set(url:string, Cookie:object) Adding a serialized cookie for a URL in a cookie store, which is attached to the cookie request header for the outgoing request.
  • CookieManager.clearAll().then((status)=>{}) Clearing all cookies from the cookie store.
  • The Cookie interface is described as:
    export interface Cookie {
      name: string;
      value: string;
      path?: string;
      domain?: string;
      version?: string;
      expires?: string;
      secure?: boolean;
      httpOnly?: boolean;
    }
    

:star: Commonly used Libraries

There are several libraries used by our partners that work well when creating a Vega Web App. Here is a list of great options to choose from:

Frameworks: react, preact (lighter weight), solid (supports lightningjs.io)
Navigation: react-tv-space-navigation (BAM), lightningjs.io (warning, uses WebGL)
Video Players: ShakaPlayer, Bitmovin, dash.js


Additional Resources

:bridge_at_night: The Message Bridge

The Message Bridge enables bi-directional communication between React Native for Vega applications and web applications through the WebView component. To send and receive messages, use the following:

React Native for Vega → Web: The injectJavaScript method.
Web → React Native for Vega: The onMessage prop.

The window.ReactNativeWebView.postMessage method runs the onMessage prop in React Native for Vega, which you can use to trigger Vega device Fire TV features. window.ReactNativeWebView.postMessage only accepts one argument, which must be a string.

<!-- index.html -->
<script>
  const message = JSON.Stringify({
    type: "announcement",
    value: "New Announcement!"
  });
  
  // use postMessage to send data to Vega Web App.
  window.ReactNativeWebView.postMessage(message);
</script>
// App.tsx
export const App = () => {

  return (
    <WebView
      ref={webRef}
      source={{ uri: 'https://amazon.com' }}
      
      onLoad={(_event: WebViewNavigationEvent) => {
        webRef.current?.injectJavaScript(`
          // injected code here to call web app
        `);
      }}
      // use onMessage to receive data from postMessage
      onMessage={(event: WebViewMessageEvent) => {
        // handle message from postMessage here
      }}
    </WebView>
  );
};
  • Useful for CL, Luca, and other Integrations
  • Useful for sending KMC commands
  • Useful for error handling and debugging when onError methods don’t apply

:rocket: Fluidity & App Performance

Fluidity is a critical aspect of user experience in TV apps. Users expect smooth, responsive interfaces, and any lag or unresponsiveness can significantly impact their perception of your app. Here are some must-read resources to help you optimize your app’s performance:

:books: Essential Reads

:test_tube: Guides and Sample Apps

:video_camera: Video Tutorials


Video Playback

Efficient video playback is at the heart of many TV apps. Vega provides powerful tools for implementing smooth, feature-rich video experiences:

Understanding headless playback is crucial for creating apps that can continue playing media even when the user navigates away from the video screen or when the TV is in a low-power state.

These resources will help you structure your app efficiently and integrate it seamlessly with the Vega ecosystem and CI/CD processes.


Amazon Fire TV Features

Leverage Amazon-specific features to enhance your app’s functionality and user experience:

These features can significantly enhance your app’s integration with the Fire TV ecosystem, improving discoverability and user engagement.

1 Like