MDN’s new design is in Beta! A sneak peek: https://blog.mozilla.org/opendesign/mdns-new-design-beta/

Site author guide for click-to-activate plugins

Plugins are a security and performance problem for Firefox users. For this reason, Firefox requires users to actively choose to activate plugins on each site that needs them. Because of this, website authors should not rely on plugins starting immediately after they have been inserted into the page. From Firefox 47 onward, non-Flash plugins are not activated by default, and starting in 2017 Flash will also be click-to-activate by default. This guide contains some best practices for site authors so that their sites do not break when using plugins.

Note: This article is intended for developers and website administrators. If you need help using a plugin in Firefox, please visit Why do I have to click to activate plugins? on support.mozilla.org.

Don't use plugins!

The #1 way to avoid user problems with click-to-activate plugins is not to use plugins! Many things that used to require plugins no longer do:

  • Cut/Copy/Paste functionality no longer requires Flash. Libraries such as Clipboard.js are available.
  • Audio and video playback and streaming is a native part of the web platform and no longer requires Flash. See our video and audio tutorial for more information, or use prebuilt libraries such as JWPlayer.
  • HTML now supports upload of multiple files and entire directories of files, which used to require the Flash player. See library examples such as fineuploader and dropzone.js.

Use script to determine if a plugin is installed

To detect if a plugin is installed, query navigator.mimeTypes for the plugin MIME type you intend to use. This allows you to differentiate between plugins that are not installed and those that are click-to-activate. Do not iterate through navigator.mimeTypes or navigator.plugins, because plugin enumeration may be removed as a privacy measure in a future version of Firefox.

function isFlashAvailable() {
  return 'application/x-shockwave-flash' in navigator.mimeTypes;
}

Google Chrome behaves differently than Firefox. The Chrome "HTML5 By Default" feature will hide Flash from navigator.plugins by default and only include it if the users chooses to allow Flash. For details see Flash Activation: Browser Comparison.

Allowing users to activate plugins

The primary UI for a user to activate a plugin is the visible plugin element. This is a box representing the plugin with an explanation that the user must explicitly allow the plugin to run.

Screenshot of the silverlight plugin activation on the Netflix website.

There are some cases where users cannot click on the plugin element:

  • The plugin is too small
  • The plugin is hidden
  • The plugin is covered by other content.

In these cases, users may be unable to activate Flash and become confused. Even if the plugin element will eventually be hidden, pages should create the plugin element visible on the page, and should resize or hide it only after the user has activated the plugin. This can be done by calling a JavaScript function when the plugin is activated.

function pluginCreated() {
  // We don't need to see the plugin, so hide it by resizing
  var plugin = document.getElementById('myPlugin');
  plugin.height = 0;
  plugin.width = 0;
  plugin.callPluginMethod();
}

The HTML, by default, specifies the Flash object to be of a size which makes it visible, like this:

<!-- Give the plugin an initial size so it is visible -->
<object type="application/x-shockwave-flash" data="myapp.swf"
      id="myPlugin" width="300" height="300">
  <param name="callback" value="pluginCreated()">
</object>

The callback parameter defined in the HTML can be called in Flash using its flash.external.ExternalInterface API.

Using a script callback to determine when a plugin is activated

Similarly, a site's script shouldn't attempt to call a plugin immediately upon creation. Instead, the plugin object should call into a JavaScript function upon creation. That function can then issue the call into the plugin, knowing that everything is set up and ready to go.

First, you set your up your HTML with a callback that calls the JavaScript function pluginCreated(), like this:

<object type="application/x-my-plugin" data="somedata.mytype" id="myPlugin">
  <param name="callback" value="pluginCreated()">
</object>

The pluginCreated() function is then responsible for the setiup of your script and any calls back into the plugin that you need to make:

function pluginCreated() {
  document.getElementById('myPlugin').callPluginMethod();
}

See also

Document Tags and Contributors

 Contributors to this page: bsmedberg, cpeterson, Sheppy
 Last updated by: bsmedberg,