Extensions Guide

Introduction

Twitch extensions allow broadcasters to embed interactive, custom, third-party content on their channel pages. Extensions installed by a broadcaster are automatically visible to any viewer who goes to the broadcaster’s channel page using a desktop Web browser. Viewers can see details about the extension and report an extension for bad behavior.

Extensions have several components:

  • An HTML/JavaScript front end for the broadcaster's installation configuration. This is rendered as part of the normal extension installation flow, permitting one-time or infrequent setup.
  • An HTML/JavaScript front end for the viewer’s experience. This is rendered in an iframe (inline frame) on the channel page.
  • An optional HTML/JavaScript front end for the broadcaster’s live experience. This is rendered in an iframe on the broadcaster’s live dashboard page. This allows the broadcaster to perform privileged operations while live (e.g., creating a new poll).
  • An optional Extension Backend Service (EBS), a Web-service backend which stores data or state and communicates with the front ends, by either receiving AJAX requests or using Twitch's PubSub architecture to broadcast to all viewers. See Architecture Overview.

There are two types of extensions:

  • A panel extension appears in the panel area below the video player.
  • A video-overlay extension renders on top of the video player as a transparent overlay.

Code samples are available on the Get Started page of the Twitch dev site.

The Broadcaster’s Experience

Broadcasters can browse and install extensions on their Dashboard’s Extension Manager tab. They can find extensions, add/remove them on their channels, and activate/deactivate them.

Installing an extension on a channel does not make it active on the channel page. To do that, after the broadcaster installs an extension, he configures the extension (if required by the developer), then activates it to make it visible to all viewers.

Heads Up: Top Reasons Why Your Extension May Get Rejected

Reason How to Avoid
Extension does not have a review link with the extension live on Twitch. When submitting an extension for review, fill in the Name of Channel for Review field with a valid URL from the twitch.tv domain.
Extension does not contain a screenshot or icon. Include an icon and at least one screenshot that accurately represent the extension front end.
Extension issues console.log commands to the browser. Do not submit an extension that issues any console.log commands.

For details, see Submitting Your Extension for Review and Guidelines and Policies.

Getting Help

If you have an issue, need more information, or have a question about anything in this guide, please visit the Extensions category of the Twitch Developer Forums.

Architecture Overview

Architecture

Extensions are front-end iframes. Typically they communicate via AJAX with an Extension Backend Service (EBS): a Web service that is developed, deployed, and maintained by the Extension developer.

While an extension is being tested, the iframe and all its assets are sourced from a URL provided by the extension developer, allowing rapid development iteration. Once the extension is ready for review by Twitch, and later in production, assets to be hosted by Twitch are copied to the Twitch CDN (Content Delivery Network) and served from there.

An extension's iframe must import the Extension Helper JavaScript file, created and hosted by Twitch, which provides methods for dealing with authentication, receiving notifications of stream properties, and listening to PubSub events. Twitch PubSub is a system that allows backend services to broadcast real-time messages to clients.

Opaque IDs

The Extension Helper provides:

  • Callback functions that are invoked with context information about the channel being viewed (e.g., video resolution, latency to the broadcaster, and channel ID)
  • An opaque identifier that identifies a viewer without revealing his Twitch identity. Using the opaque ID, developers can determine a viewer’s authenticated state. Logged-out users also have an opaque ID, but it is not guaranteed to be the same between channels or sessions.

Opaque IDs persist across all channels, and they do not change unless the viewer explicitly requests to rotate his identity. Developers are encouraged to use their EBS to store per-viewer information, using opaque IDs as keys. If your extension needs to know the viewer’s numeric Twitch ID, check the box under Request Identity Link in the extension’s Extension Capabilities section. Once the viewer accepts your request to share his Twitch identity, his numeric Twitch ID is provided in the Extension Helper's onAuthorized() callback function. For details about this callback and the JWT format, see the Extensions Reference.

An opaque ID that begins with “A” is a logged-out user and should not be persisted. It will change every time the logged-out user loads your extension.

Authentication Tokens and Scopes

The Extension Helper provides the iframe with an authentication JWT (JSON Web Token). When the iframe wants to communicate with its EBS, it sends this token in an HTTP header to the EBS. The JWT is signed by Twitch, using a secret shared between Twitch and the extension developer. The EBS can then use this secret to verify the incoming JWT and ensure that received messages are from a legitimate source. Also, the JWT itself contains reliable information about the role of the sender; e.g., whether the incoming message is from a viewer or a broadcaster.

Focus

When a viewer clicks into an extension, Twitch sends focus back to the player, to ensure that keyboard shortcuts for the player continue to work. However, if an extension asks viewers to click on a form field element (for example, "field," “select,” “textarea”), and the viewer does so, the focus stays on the form element.

In the Firefox browser, there is a known issue that prevents these input types from capturing focus.

Design Best Practices

Design is subjective, so we do not dictate what "good design" means on our platform. However, there are several best practices you should consider, to ensure that your extension is a good experience for your audience. Please take these into account whenever you develop an extension.

  • Branding — Your extension’s branding should be clean, recognizable, and unique. In general, use your logo sparingly and use brand color to enhance your brand on Twitch. Your extension cannot include Twitch-branded elements, including the Twitch or Glitch logos.

  • Color — Use a limited color palette. If your extension is for a specific game, use a complimentary color palette where appropriate. For a video-overlay extension, consider how it will blend into the content behind the extension (video, game data, or other stream-overlay components). Use a key color for emphasis and calls to action. Avoid using the same colors for interactive and noninteractive elements.

  • Contrast and accessibility — Always provide enough contrast between colors, to ensure your designs are as accessible as possible. Avoid links on backgrounds that are of similar contrast. Consider your color-blind audience.

  • Layout — Use alignment and hierarchy for ease of visual scanning. Also see the "video-overlay considerations" below.

  • Typography — Use font weight, size, and color for emphasis. If possible, try to use a single font; using multiple fonts can make your extension feel fragmented. Instead, use font styling (bold, italic) and a limited number of font sizes. Use built-in browser fonts: they perform best and and work on all browsers. Here are some Web-safe fonts:

    • Serif: Georgia, Palatino Linotype, Times New Roman
    • Sans serif: Arial, Helvetica, Comic Sans MS, Impact, Lucida Sans Unicode, Lucida Grande, Tahoma, Geneva, Trebuchet MS, Verdana
  • Extensions on mobile — Overlay and panel extensions are not supported on the Twitch mobile app or mobile website.

  • Panel considerations — Panel extensions are limited to 320px wide x 500px high, to avoid iframe scrolling. Within this box, try to allow 10px of inner padding for any text within your extension, for maximum readability.

  • Stateful feedback — Preload wherever possible, especially on overlay extensions. Overlay extensions should avoid the use of "loading" indicators, which can interfere with the viewing experience. If a panel extension needs to display a loading state, design your loading state to be as clear and concise as possible. Consider adding a loading indicator. Use status indicators to communicate updates, errors, and other statuses that your extension may require; your audience should not have to guess what is happening during a call to action.

  • Navigation — In general, extensions should avoid multi-layered navigation. If you must have hierarchical navigation, always provide a clear path, to let users know where they are. Ask yourself if each navigation element is necessary.

Video Overlay Design Considerations

Video-overlay extensions are meant to enhance the viewer’s experience, so be aware that each extension element covers valuable real estate.

  • Sizing — When designing your extension UI, take into consideration that it needs to scale and adapt when the browser and video player resize. By default, a video-overlay extension functions at all sizes while the broadcaster is live. Consider hiding your extension when the size is reduced to a point that the extension becomes non-functional.

  • Covering up player elements — If you have extension UI elements over the Twitch video player, interactions with those elements may not work. Here is a diagram of areas to consider when you design your video-overlay extension:

Video player elements

  • iFrame boundaries — For drag-and-drop elements, consider how your video-overlay extension will respond when a user tries to move an element outside the video player’s viewing area. Design your extension to block elements from being relocated to outside the viewing area and/or force them to "spring" back into the viewing area.

  • Disabling — A video-overlay extension disables itself when the broadcaster goes offline or hosts another channel. When a viewer pauses the video, the extension iframe is hidden until the viewer unpauses the video.

  • Player control layers — Keep in mind that your video-overlay extension will be rendered below all our video-player controls, such as pop-up menus, mouseovers, LIVE indicator, and channel information in the top left of popout/ember versions of the video player. Remember that theater mode, full screen, and embed have different UI layouts than the "normal" Twitch player.

Layers

Extension Life Cycle

Each version of your extension is managed independently in the Extensions section of the developer site. For each version, the Version Status tab allows you to control the lifecycle of your extension.

Every version of every extension begins in Local Test. While a version is in Local Test, all assets (HTML, JavaScript, CSS, images, fonts, etc.) are served from the defined testing base URI.

When the developer is satisfied with the locally-hosted test version, he transitions it to Hosted Test. This uploads all extension assets to the Twitch CDN, allowing the developer to ensure that the extension still works when served from Twitch. Some sanity checks are performed on upload, such as making sure icons and screenshots are appropriately sized. While in either Local Test or Hosted Test, extensions are visible only to a developer-provided list of test accounts and a small subset of Twitch staff.

Once the hosted test is complete, the developer can submit the extension for Review. The developer can submit the extension for review as many times as he wants, but only one version of an extension can be in review at a time. Once a version is submitted, the only way to change it is to put the extension back into Hosted Test and upload the assets again. While in review, all test accounts can continue to test the extension as before.

After the extension is reviewed by Twitch, it is placed into one of three states:

  • Pending Action indicates that revisions are required. Using the provided author email address, the developer is contacted and told the reason(s) the extension was not approved. The developer can then take the extension back to a Test state, iterate on the issues, and re-submit the extension for review. No new version needs to be created.
  • Rejected indicates that Twitch feels the extension is inappropriate and will not be accepted under any circumstances. This causes a permanent revocation of the extension’s Client ID (a unique identifier). Rejected is a permanent, terminal state.
  • Accepted causes the developer to be notified that he can make the extension live at any time. Accepted extensions may be transitioned back to a Test state if necessary, but this incurs another full review cycle.

To go live, the developer clicks Release on the version that was Accepted. It then becomes publicly visible and can no longer be updated, only replaced with a new version. When a new version is Released, any previous released version is transitioned to Deprecated, and any installations of that extension are immediately upgraded.

When a new version is Released, developers should:

  • Be aware that some viewers or broadcasters may be using the old version at that very moment.
  • Ensure that their EBS can handle traffic from older versions that have not yet been refreshed.

Creating Your Extension

To get started with extensions, you will use the Twitch developer site. This is where you create extensions, manage extensions, and submit extensions for review by Twitch.

  1. Log in to the Twitch developer site with your Twitch ID.
  2. Navigate to the Extensions page, then click Create Extension.
  3. Complete each field in the Create Extension form
    • Name — The name of your extension. This cannot be changed later, so double-check the spelling.
    • Type of Extension — Select Panel or Video Overlay.
    • Summary — This will be viewable by broadcasters on the extensions listings page in the Extension Manager. It should be 1-2 brief sentences describing what your extension does. To provide more detail, use the Description field.
    • Description — More detail than the Summary about the functions of your extension.
    • Author name — The full name of the extension author or organization that will receive credit on the Extension Manager. This can be changed later.
    • Author email — Contact information for the extension creator. This is used to contact the developer with information about the extension’s lifecycle (e.g., reject/accept notifications). Twitch will never reveal this email to anyone on the site.
    • Support email — Public contact information for support-related queries from broadcasters.
  4. (Optional) Add a logo for your extension. This must be 100px x 100px. Do not use Twitch or Glitch logos. If you do not have a logo, a default logo will be assigned.
  5. Click Create Extension to create your extension. You will get a verification email soon after creation.

Congratulations, you've created an extension! Be sure to check your email, as you will need to verify ownership of the provided author email address.

To change your extension’s description, summary, author name, or logo, click the Settings tab after your extension is created. These fields are not version specific: they apply to all versions of the extension.

Managing Extension Versions

After you click Create Extension, you are placed into the Version Status section of the Versions tab. Here, you can see the state of your extension in the extension life cycle and change the state as needed. On the left navigation bar, you will see additional sections to manage your extension version; these are described below.

Version Assets

When you are ready to upload your assets to the Twitch CDN, zip up your assets and upload them in the Version Assets section. You cannot submit your extension for review until you upload the assets to Twitch's CDN. For more information, see Hosted Test.

Extension Capabilities

Each extension is unique, and Twitch has optional capabilities to maximize your extension’s potential. These are in the Extension Capabilities section.

  • If your extension needs to know the viewer’s numeric Twitch ID, checkmark the Request Identity Link box. Once the viewer accepts your request to share his Twitch identity, his numeric Twitch ID is provided in the Extension Helper's onAuthorized() callback function. For details about these callbacks and the JWT format, see the Extensions Reference.

  • You can optionally require that a broadcaster successfully configure your extension before activation is allowed. This can be useful if, for example, an active extension would show a confusing error message to all viewers if misconfigured. You enforce required broadcaster configuration with a string in the Required Configurations field. The contents of this string can be whatever you want. This is covered further in Creating Your Extension Backend Service (EBS).

  • If your application needs to perform actions on behalf of the broadcaster, the required OAuth scopes must be added to Required Broadcaster Abilities. Using this comma-separated list of OAuth scopes, we set up the authorize call with the specified redirect URI, so when the user accepts the scopes your application requests, we will use that redirect URI to send you the user’s token. (See the Twitch Authentication guide for a list of scopes.) This is covered further in Creating Your Extension Backend Service (EBS).

  • Optionally, if your extension is required to open an external URL for configuration or as a core functionality for the panel, list the URLs under Whitelisted Config URLs or Whitelisted Panel URLs. Linking to an external site for a video overlay extension is strictly prohibited.

Asset Hosting

After your extension’s initial creation, you will need to update the default paths for your assets, in the Asset Hosting section of the extension version you are editing.

  • Change your Testing Base URI to reflect the root URI for all assets related to this extension version. The URI must end with a forward slash. The URI is completely up to you; it need not match the version in any way. During test, the assets are served directly from this URI, so you can update your code without re-submitting anything. For more information on how to test locally, see Local Test.
  • The Viewer Path contains the HTML file that is shown to viewers on the channel page. This page is presented to viewers in either the panels area or the video overlay, depending on the extension's specified anchor.
  • The Config Path contains the HTML file that is shown to broadcasters while they are configuring the extension but before activating it within the Extension Manager. This page is displayed in an iframe with dynamic width and fixed height (720px). This should be a path relative to the testing base URI. It should be used for infrequent, install-time configuration.
  • The optional Live Config Path contains the HTML file that is shown to broadcasters in the Live module of the Dashboard. It is used for broadcaster actions taken while the extension is active, such as creating a new poll. It should be a path relative to the testing base URI.

Access

Add the account IDs of all accounts being used to test the extension, under Testing Accounts in the Access section. Specify a comma-separated list of account IDs (not names) which have access to this version of the extension while it is in test.

You may want to add the account IDs of specific broadcasters to the Broadcaster Whitelist. This prevents broadcasters outside the whitelist from installing the extension once it is approved. If this is empty or missing, all broadcasters can use this extension. To convert account names to account IDs, see Translating from User Names to User IDs.

Creating Your Extension Front End

As previously defined, extensions are front-end iframes. Now that you have created your extension and defined the settings of the first version of the extension, you are ready to create the assets that will live within the iframe.

The Extensions Boilerplate

To help our developers get started developing extensions as fast as possible, we provide the Extensions Boilerplate. It provides a starting point for developing your extension and an easily deployable, local testing environment for rapid iteration.

Navigate to The Extensions Boilerplate Github page and follow the instructions to clone and deploy your local version.

Extension Helper Library

An extension's iframe must import the Extension Helper JavaScript file, created and hosted by Twitch. It provides methods for dealing with authentication, receiving notifications of stream properties, and listening to PubSub events. Each HTML defined in the Asset Hosting section of your extension (Viewer, Config, Live Config) must load the Extension Helper. To do so, include this line:

<script src="https://extension-files.twitch.tv/helper/v1/twitch-ext.min.js"></script>

For more details on the Extension Helper, including the callbacks and functions it provides, see the Extensions Reference.

Managing Extension Secrets

Each extension maintains a shared secret that is used to sign and verify JSON Web Tokens (JWT) that provide the identity of users. Use this authentication method when making extensions API calls from your EBS (for endpoints that support it).

Twitch extension technology relies on a secret shared between the Twitch API and the EBS, to validate JWTs. This secret has an extremely long life (100 years); however, we strongly recommend that extension developers rotate the shared secret often, to better ensure its security.

JWT Roles

Both the EBS and Twitch create JWTs.

The EBS should create and sign JWTs with the external role to perform API actions. Twitch creates JWTs with other roles, so the EBS can perform user authentication. Both use cases (the external role and other roles) use the same secret. (For a discussion of roles, see “JWT Schema” in the Extensions Reference.)

Creating Your First Secret

  1. Go to the Settings page on your extension in the Extensions Dashboard.
  2. On the left panel, click Secret Keys.
  3. Click Create New Secret to generate a new secret key. You will see the following:
    • Key — The secret, base64 encoded.
    • Active — UTC timestamp when the secret becomes active. This allows the secret to propagate through both Twitch servers and the EBS, before you use it.
    • Expires — Timestamp when the secret expires. This is the latest time to use this secret to verify a JWT; the JWT should be discarded after this time.

Rotating Secrets

You must rotate your secrets before they expire. To do so, create a new secret on the extension’s Settings page under Secret Keys. The table will update, showing when the previous key will expire and the new key will be active.

Because of the activation delay, you can have multiple secrets active for some (configurable) period of time. For signing, use the active secret with the latest expiration time.

Optionally, you can create new secrets with the Create Extension Secret endpoint. For a higher level of security, you can programmatically rotate secrets on a scheduled basis.

Revoking All Secrets

At any time, if your secrets are compromised, the Revoke All Secrets option can be used on the extension’s Settings page under Secret Keys. View this as a kill switch: it immediately deletes all secrets associated with a specified extension.

Optionally, you can revoke all secrets through the Revoke Extension Secrets endpoint.

Creating Your Extension Backend Service (EBS)

The EBS is your optional backend service that supports the extension. Your EBS can be written in whatever language you prefer. Depending on the nature of your extension it should generally be capable of the following operations:

Verifying the JWT

Your EBS needs to verify the communication it receives via any AJAX call from your extension. For example, it may need to enforce a policy that certain configuration tasks can be performed only by broadcasters. It also may want to ensure that a confirmed Twitch viewer, as opposed to an unidentified agent, is connecting to the EBS. As described above, the front-end iframe can obtain a signed JWT via the Extension Helper, using the onAuthorized() callback. The extension developer may then include this token as a header when making AJAX calls to the EBS.

JWT signing and validation libraries are available for many languages at https://jwt.io. They usually follow a calling interface similar to this:

verify(<jwt>, <secret>)

Where:

  • <jwt> is the token received from the Twitch backend via the Extension Helper and passed as a header to the EBS.
  • <secret> is the previously established shared secret.

The JWTs used by Twitch extensions expire, and verification of them fails after the expiration date. The Extension Helper automatically refreshes the token and then re-calls the onAuthorized() callback. Always use the latest JWT supplied by the Extension Helper.

For the full JWT schema and detailed notes on each field, see "JWT Schema" in the Extensions Reference.

Signing the JWT

In addition to verifying tokens signed by the Extension Helper, your EBS needs to be able to sign new JWTs for calls to various extensions endpoints that use JWT as the authentication mechanism. For JWTs signed by your EBS, use the following format:

{
  "exp": 1502646259,
  "user_id": "27419011",
  "role": "external"
}

Where:

  • exp is the Unix epoch timestamp when the token will expire. Be sure to provide a buffer, to allow potential positive time drift.
  • user_id is the Twitch user ID that owns the extension.
  • role is set to external.

For more information about these fields, see the “JWT Schema” section of the Extensions Reference.

Sign the token using your JWT library. They usually follow a calling interface similar to this:

sign(<token>, <secret>)

Where:

  • <token> is the token object created in the previous step.
  • <secret> is the previously established shared secret.

Send your signed JWT in the request header, following this format:

Authorization: Bearer <signed JWT>

Broadcasting via PubSub

When the EBS wants to transmit realtime messages or state via PubSub, it will use the Send Extension PubSub Message endpoint. Using this endpoint, your EBS can broadcast to all viewers of a given channel, or to specific user’s via a whisper.

Please be aware of the following technical guidelines for using Twitch PubSub:

  • 1 message per second per channel
  • 5 KB message size

These guidelines ensure the stability and scalability of our systems.

Requesting Broadcaster Abilities

If your application needs to perform actions on behalf of the broadcaster, the required OAuth scopes must be added to the Required Broadcaster Abilities, as described above in Extension Capabilities.

Once your EBS receives the OAuth callback and you receive the access token, call the Set Extension Broadcaster OAuth Receipt endpoint.

When you create your extension, an OAuth application is automatically registered for you, with a redirect URI set to https://localhost/. Once you move your extension into hosted testing, you should set this application redirect URI to wherever your EBS is hosted.

Required Configurations

Optionally, you can require that a broadcaster successfully configures your extension before activation is allowed. This can be useful if, for example, an active extension would show a confusing error message to all viewers if misconfigured. You enforce required broadcaster configuration with a string in the Required Configurations field. The contents of this string can be whatever you want. By using a string you provide within this field, you can easily require different configurations from version to version, so that if a new version requires reconfiguration, the broadcaster will need to complete configuration before activating the new version.

Once your EBS determines that the extension is correctly configured on a channel, call the Set Extension Required Configuration endpoint.

Testing Your Extension

After creating your extension and setting its capabilities, you are ready to begin testing and development. Extension development typically involves iterating locally over the extension and EBS, then transitioning your extension into a hosted state for additional testing and verification.

Local Test

To locally test your extension, you can use the Extensions Boilerplate or whatever you like, to act as a local Web server. Since some operations require HTTPS, you need to create and install a self-signed certificate on your system.

You can install your extension on your own channel, in the Extension Manager section of the Broadcaster Dashboard. While your extension is in Local Test or Hosted Test mode, only viewers on the testing whitelist can see it. Other viewers see your channel without any extensions.

Follow these steps:

  1. While logged in to Twitch, visit https://www.twitch.tv/dashboard.
  2. Click the Extension Manager tab.
  3. Install the extension into your account from the Extension Manager.
  4. If you are directed to configure the extension, see Required Configurations.
  5. Click Activate.
  6. Test your extension.

Hosted Test

When you are ready to begin testing your extension from the Twitch CDN:

  1. Gather your front-end assets into a valid ZIP format, retaining the directory structure. Ensure that:
    • Files are placed in the root of the ZIP directory.
    • You do not include non-extension files.
  2. On the Extensions Dashboard, go to the Versions tab for your extension.
  3. On the left panel, click Version Assets.
  4. Choose the appropriate ZIP file.
  5. Click Upload Assets.

This copies your assets to, and begins serving them from, the Twitch CDN. In this state, all your assets are hosted on the Twitch CDN, but the review process is not started. This gives you an opportunity to test your extension while hosted on the CDN.

If there is an issue with the upload (e.g., a file could not be accessed or your images are improperly sized), you are notified by email. To get these notifications, you must have verified the author email when creating the extension. Make sure you received a verification email when you created the extension on the dashboard and you clicked on the link in the email. If you have not done this, you will not get email notifications about any file-upload issues or when your extension is approved.

Submitting Your Extension for Review

Once your extension works properly on the Twitch CDN, it is ready to be submitted for review. Before submitting, please fill out the EULA or Terms of Service URL and Privacy Policy URL fields within Version Details on the version of the extension you want to submit.

We recommend you include screenshots of your extension in action, by uploading images in the Screenshots section of the extension. Images can be PNG, JPG, or GIF. The minimum (and recommended) image size is 1024x768. Images must have a 4:3 aspect ratio. You must have at least one screenshot (and an icon) for your extension before submission.

Before submitting your extension for review, you must complete the Review Details section of the version you will submit. Pay special attention to the following fields and issues:

  • Name of Channel for Review — Specify the URL of the channel that you want to be used for the review process. To complete our review of your extension, we require the version under review to be fully functional and live on a Twitch channel page until it is approved. Also, if your extension requires live data to operate, please simulate the necessary data to allow our reviewers to use the full breadth of features offered by your extension.

    This field is required. Your extension will be rejected unless this field contains a valid URL from the twitch.tv domain.

  • Walkthrough Guide and Change Log — To facilitate a quick review, we highly recommend you provide a clear and thorough walkthrough guide documenting your extension’s features.

    If you are releasing a new version, please include a change log.

    Failure to provide a walkthrough guide or change log may result in extended review time or rejection.

Once you’ve completed the Review Details section, you can submit your extension for review by clicking Mark In Review in the Version Status section on the version for which you have uploaded assets.

Do’s and Don’ts

To ensure that your extension is a great experience for broadcasters and viewers, Twitch has policies that you must adhere to. During the review process, we check your extension against these policies. We reject extensions that do not adhere to our policies.

A full list of policies is in Guidelines and Policies. The most common issues are listed below, as a guide before you enter review. To minimize review time and the possibility of rejection, follow all these steps.

Do:

  • Ensure that your extension has an icon and at least one screenshot that accurately represent the extension front end.
  • Submit human readable, non-obfuscated code.
  • Include the Twitch Extension Helper as your first JavaScript file.
  • Make sure all aspects of your extension's functionality can be accessed on your test stream during the review period.
  • Ensure that your extension summary and details accurately describe your extension.
  • Include all clickable and displayed URLs that are presented to users in your extension in the Extension Capabilities section of the version manager.
  • Use the HTTPS protocol handler everywhere required (not HTTP).
  • If your extension requires OAuth, include the required OAuth scopes inside the required_broadcaster_abilities field in the extension configuration.
  • Load JavaScript and CSS only from the Twitch extension CDN.
  • Ensure that your extension and extension backend are stable during review.

Don’t submit an extension which:

  • Issues any console.log commands.
  • Has any links which try to open browser windows in a video-overlay extensions.
  • Has any audio (including sounds or music) playing in the extension.
  • Contains advertisements or sponsorship content (excepting your own developer branding).
  • Encourages or rewards users for visiting or taking action on a site that is not owned and operated by Twitch or Amazon.
  • Sells an upgraded experience off the Twitch platform.
  • Sells anything on a page that can be visited by an extension link.
  • Uses Flash, browser extensions, or browser plug-ins.
  • Uses pop-up alerts in any manner.
  • Uses eval in your JavaScript code.
  • Generates Iframes within HTML files.
  • Render AJAX directly in the browser window.
  • Collect or store data on a Twitch user, except:
    • To create compelling benefits that both improve the Twitch user experience in your apps and are exclusive to the Twitch platform.
    • To send administrative communications, such as facilitating the redemption of digital items to users or notifying an end user of updates for customer-service purposes.
    • To send periodic promotional materials or notifications about features and benefits of your apps that are targeted to all Twitch users (provided that you present a mechanism to allow an end user to unsubscribe to promotional communications and the primary purpose of such communications is not to promote or drive Twitch users to competing products or platforms).
    • As necessary to process transactions.

Making Changes

While your extension is under review, you cannot change any version assets or details. If changes are needed, revert back to the test version by clicking Return to Testing. After making the changes, upload your modified assets to the Twitch CDN, then re-submit the version for review. Note that re-submitting resets your place in the review queue.

Releasing Your Extension

Once an extension is approved, you release it for live use by clicking the Release button on the version that was approved. If a prior version of your extension already has a state of Released, the state of that version automatically is changed to Deprecated. For a given extension, only one version can be in the Released state at a time.

Updating Your Extension

To update your extension after it is released, you must create a new version of the extension and submit it for review. To create a new version, start by clicking the Versions tab within the extension you want to manage. This displays a table with all extension versions and their statuses.

Once the new version of your extension is approved, you can Release it live to broadcasters to use. This retires your previous extension, which is displayed on the bottom of the Version Status page.

Deleting Your Extension

If you decide to no longer support your extension, you can choose to delete your extension: click the Delete Extension button from the Settings section of your extension. This removes your extension from all broadcasters Extension Manager pages.

You cannot delete specific versions of your extension. Deleting an extension is irreversible.

Guidelines and Policies

Technical Guidelines

For released extensions, all HTML, JavaScript, and CSS files must be served from the Twitch CDN. When crafting the broadcaster’s and viewer’s HTML, JS, and CSS files that eventually will deploy to Twitch edge servers, follow the guidelines below. If you fail to do so, Twitch probably will not approve your extension.

  • Do not submit an extension that issues any console.log commands.
  • Do not use eval() statements. If you rely on libraries that use eval(), do not combine those libraries into any minified JavaScript, but instead source them separately so our reviewers can know the source of any eval() statements.
  • Remove all JavaScript console logging before submitting your extension for review.
  • Whenever possible, put all text in the .html files. When you substitute words in a dynamic string, enumerate the dynamic strings in the JavaScript code when possible. (Sometimes this is impossible.)
  • Do not inject directly into the DOM any data obtained dynamically over AJAX (e.g., JSON is fine, HTML is not).
  • Use HTML5 and UTF-8.
  • Support these browsers:
    • IE11 (Windows)
    • The two most recent Chrome versions (OS X and Windows)
    • The two most recent Firefox versions (OS X and Windows)
    • Safari 9 (OS X)
  • Include the Twitch Extension Helper in your HTML files, as the first JavaScript file. It is served from the Twitch CDN: https://extension-files.twitch.tv/helper/v1/twitch-ext.min.js
  • Extensions may not require a third-party download to work for viewers. (Additional required software for the broadcaster is acceptable.)
  • Include all JavaScript and CSS files in the extension's uploaded assets.
  • JavaScript files submitted for review can be minified but must not be obfuscated.
  • Extensions may not play audio or include code with the intent of playing audio.
  • Load all assets (images, fonts, etc.) using HTTPS.
  • Extensions may not use Flash.
  • Extensions may not use double-click as an input.
  • Extensions may not use iframes.
  • PubSub traffic must adhere to the following limits:
    • 1 message per second per channel
    • 5 KB message size

Localization Guidelines

Developers are responsible for localizing their product front ends appropriately. You can specify the client language in your extension by using either:

  • The language query parameter in the URL loading your extension (e.g., https://<ext-id>.ext-twitch.tv/<ext-id>/<version>/viewer.html?language=en)
  • The language field in the context callback

Content Policies

All extensions must abide by the following content policies. Extensions are evaluated against these content policies during review and may be rejected if they are not in compliance.

  • Extension developers must abide by the rules laid out in the Twitch Developer Services Agreement and Terms of Service.
  • All extensions must have an icon and at least one screenshot that accurately represent the extension front end.
  • All extensions submitted by a given company or individual should be generated using a single Twitch account.
  • Commerce:
    • Extensions may provide differentiated experiences or functionality to broadcasters, in exchange for compensation from broadcasters. For example, tiered access to features or purchasable plugins to add functionality.
    • Extensions may not provide differentiated experiences to viewers in exchange for compensation from viewers, except with regard to the use of Twitch/Amazon commerce instruments.
    • Extensions may not transact or encourage the transacting of monetary exchange in relation to any non-Twitch/Amazon commerce instruments.
  • No advertising or sponsorship content (static or dynamic) may be displayed in any extension.
  • Off-site linking:
    • Video-overlay extensions may not contain links of any kind.
    • Panel extensions must submit a whitelist of domains requested for off-site linking.
    • Off-site links must be related to the extension’s core functionality.
    • Off-site links may not refer users to sites that deliver functionality effectively similar to that available on Twitch.tv.
  • Settings and configuration of extension functionality must be managed through the on-site extension configuration and live dashboard iframes.
  • Extensions may not encourage or reward users for consuming Twitch content on a site other than Twitch.tv.
  • Extensions may not encourage or reward users for taking specific actions outside Twitch/Amazon properties.
  • Extensions may not request or require OAuth permissions from extension viewers.
  • Extensions may not encourage or facilitate users to break Twitch user terms of service, including:
    • No sexually explicit content.
    • No encouragement of violence, bullying, or hate speech.
    • No deceptive behavior or impersonation.
    • No facilitation of illegal activities.
  • Extensions may not use keyboard shortcuts to power functionality.
  • Extensions may not use Twitch branding, the Twitch logo, or the Twitch Glitch in their extension content.
  • Extensions may not include anything intentionally malicious or designed to circumvent Twitch security or safety precautions.
  • Extensions must respect intellectual property rights. The extension developer is responsible for any claims filed against intellectual property displayed by an extension. An extension may be removed until such claims are resolved.
  • Extensions may not use irrelevant, misleading, or excessive keywords in titles, descriptions, or metadata.
  • An extension listing must describe the functionality of the extension accurately and completely.
  • Developers may not try to manipulate an extension's placement within the extension manager or any future extension-discovery mechanism.
  • Twitch reserves the right to remove from the extension ecosystem any extension, for any reason, at any time.

Content Security Policies

To ensure the security and privacy of our viewers and broadcasters, we employ content security policies. While developing, you may see a message like this in your console:

Refused to load the stylesheet 'https://somedomain.net/bad.css' because it violates the following Content Security Policy directive: "style-src 'self' https://fonts.googleapis.com".

Please note the blocked request and update your extension accordingly, to load the resource.

By default, all assets must be loaded from the Twitch CDN, except the following:

  • You can connect to any HTTPS or WSS endpoint (i.e., for purposes of an XHR).
  • Images can be loaded from anywhere or via a data URI.
  • Google fonts are allowed as valid sources for fonts and stylesheets.

Also, the following restrictions apply:

  • You cannot use inline JavaScript.
  • You cannot load any asset or connect to any resource that is not served over a secure protocol (HTTPS or WSS).
  • You cannot embed an extension anywhere outside the Twitch extension harness.

For more detail, see https://content-security-policy.com.