blob: 6e39c1a929b8b26ea6def79fdef76443409e0be3 [file] [log] [blame]
<h1>Tutorial: Migrate to Manifest V2</h1>
<p>
Manifest version 1 was deprecated in Chrome 18,
and support will be phased out according to the
<a href="manifestVersion.html#manifest-v1-support-schedule">manifest version 1 support schedule</a>.
The changes from version 1 to version 2
fall under two broad categories:
API changes and Security changes.
</p>
<p>
This document provides checklists for migrating your Chrome extensions
from manifest version 1 to version 2,
followed by more detailed summaries of what these changes mean and why they were made.
</p>
<h2 id="api-checklist">API changes checklist</h2>
<ul>
<li>Are you using the <code>browser_actions</code> property
or the <code>chrome.browserActions</code> API?</li>
<ul>
<li>Replace <code>browser_actions</code>
with the singular <code>browser_action</code> property.</li>
<li>Replace <code>chrome.browserActions</code> with
<code>chrome.browserAction</code>.</li>
<li>Replace the <code>icons</code> property with <code>default_icon</code>.</li>
<li>Replace the <code>name</code> property with <code>default_title</code>.</li>
<li>Replace the <code>popup</code> property with
<code>default_popup</code> (and it now must be a string).</li>
</ul>
<li>Are you using the <code>page_actions</code> property
or the <code>chrome.pageActions</code> API?</li>
<ul>
<li>Replace <code>page_actions</code> with <code>page_action</code>.</li>
<li>Replace <code>chrome.pageActions</code> with <code>chrome.pageAction</code>.</li>
<li>Replace the <code>icons</code> property with <code>default_icon</code>.</li>
<li>Replace the <code>name</code> property with <code>default_title</code>.</li>
<li>Replace the <code>popup</code> property with
<code>default_popup </code>(and it now must be a string).</li>
</ul>
<li>Are you using the <code>chrome.self</code> property?</li>
<ul>
<li>Replace with <code>chrome.extension</code>.</li>
</ul>
<li>Are you using the <code>Port.tab</code> property?</li>
<ul>
<li>Replace with <code>Port.sender</code>.</li>
</ul>
<li>Are you using the <code>chrome.extension.getTabContentses()</code>
or the <code>chrome.extension.getExtensionTabs()</code> APIs?</li>
<ul>
<li>Replace with <code>chrome.extension.getViews( { "type" : "tab" } )</code>.</li>
</ul>
<li>Does your extension use a background page?</li>
<ul>
<li>Replace the <code>background_page</code> property
with a <code>background</code> property.</li>
<li>Add a <code>scripts</code> or <code>page</code>
property that contains the code for the page.</li>
<li>Add a <code>persistent</code> property and set it
to <code>false</code> to convert your background page
to an <a href="event_pages.html">event page</a></li>
</ul>
</ul>
<h2 id="security-checklist">Security changes checklist</h2>
<ul>
<li>Are you using inline script blocks in HTML pages?</li>
<ul>
<li>Remove JS code contained within &lt;script> tags
and place it within an external JS file.</li>
</ul>
<li>Are you using inline event handlers (like onclick, etc)?</li>
<ul>
<li>Remove them from the HTML code,
move them into an external JS file and
use <code>addEventListener()</code> instead.</li>
</ul>
<li>Does your extension inject content scripts into Web pages
that need to access resources (like images and scripts)
that are contained in the extension’s package?</li>
<ul>
<li>Define the <a href="manifest/web_accessible_resources.html">web_accessible_resources</a>
property and list the resources
(and optionally a separate Content Security Policy for those resources).</li>
</ul>
<li>Does your extension embed external Web pages?</li>
<ul>
<li>Define the <a href="manifest/sandbox.html">sandbox</a> property.</li>
</ul>
<li>Is your code or library using <code>eval()</code>, new <code>Function()</code>,
<code>innerHTML</code>, <code>setTimeout()</code>, or otherwise passing strings
of JS code that are dynamically evaluated?</li>
<ul>
<li>Use <code>JSON.parse()</code>
if you’re parsing JSON code into an object.</li>
<li>Use a CSP-friendly library,
for example, <a href="http://angularjs.org/">AngularJS</a>.</li>
<li>Create a sandbox entry in your manifest and
run the affected code in the sandbox,
using <code>postMessage()</code> to communicate
with the sandboxed page.</li>
</ul>
<li>Are you loading external code,
such as jQuery or Google Analytics?</li>
<ul>
<li>Consider downloading the library and
packaging it in your extension,
then loading it from the local package.</li>
<li>Whitelist the HTTPS domain that serves the resource
in the "content_security_policy" part of your manifest.</li>
</ul>
</ul>
<h2 id="api-summary">Summary of API changes</h2>
<p>
Manifest version 2 introduces a few changes
to the browser action and page action APIs,
and replaces a few old APIs with newer ones.
</p>
<h3 id="browser_actions">Changes to browser actions</h3>
<p>
The browser actions API introduces some naming changes:</p>
<ul>
<li>The <code>browser_actions</code> and
<code>chrome.browserActions</code> properties have been replaced
with their singular counterparts <code>browser_action</code>
and <code>chrome.browserAction</code>.</li>
<li>Under the old <code>browser_actions</code> property,
there were <code>icons</code>, <code>name</code>, and
<code>popup</code> properties.
These have been replaced with:</li>
<ul>
<li><code>default_icon</code> for the browser action badge icon</li>
<li><code>default_name</code> for the text that appears in the tooltip when you hover over the badge</li>
<li><code>default_popup</code> for the HTML page that represents the UI
for the browser action (and this must now be a string, it cannot be an object)</li>
</ul>
</ul>
<h3 id="page_actions">Changes to page actions</h3>
<p>Similar to the changes for browser actions,
the page actions API has also changed:</p>
<ul>
<li>The <code>page_actions</code> and <code>chrome.pageActions</code> properties
have been replaced with their singular counterparts
<code>page_action</code> and <code>chrome.pageAction</code>.</li>
<li>Under the old <code>page_actions</code> property,
there were <code>icons</code>, <code>name</code>,
and <code>popup</code> properties.
These have been replaced with:</li>
<ul>
<li><code>default_icon</code> for the page action badge icon</li>
<li><code>default_name</code> for the text
that appears in the tooltip when you hover over the badge</li>
<li><code>default_popup</code> for the HTML page
that represents the UI for the page action
(and this must now be a string, it cannot be an object)</li>
</ul>
</ul>
<h3 id="removed_and_changed">Removed and changed APIs</h3>
<p>
A few extension APIs have been removed and replaced with new counterparts:
</p>
<ul>
<li>The <code>background_page</code> property has been replaced
by <a href="background_pages.html">background</a>.</li>
<li>The <code>chrome.self</code> property has been removed,
use <code>chrome.extension</code>.</li>
<li>The <code>Port.tab</code> property has been replaced
with <code>Port.sender</code>.</li>
<li>The <code>chrome.extension.getTabContentses()</code> and the
<code>chrome.extension.getExtensionTabs()</code> APIs have been replaced
by <code>chrome.extension.getViews( { "type" : "tab" } )</code>.</li>
</ul>
<h2 id="security-summary">Summary of security changes</h2>
<p>
There are a number of security-related changes
that accompany the move from manifest version 1 to version 2.
Many of these changes stem from Chrome’s adoption of
<a href="contentSecurityPolicy.html#H3-1">Content Security Policy</a>;
you should read more about this policy to understand its implications.
</p>
<h3 id="inline_scripts">Inline scripts and event handlers disallowed</h3>
<p>
Due to the use of <a href="contentSecurityPolicy.html">Content Security Policy</a>,
you can no longer use &lt;script> tags that are inline with the HTML content.
These must be moved to external JS files.
In addition, inline event handlers are also not supported.
For example, suppose you had the following code in your extension:
</p>
<pre>
&lt;html>
&lt;head>
&lt;script>
function myFunc() { ... }
&lt;/script>
&lt;/head>
&lt;/html>
</pre>
<p>
This code would cause an error at runtime.
To fix this, move &lt;script> tag contents to external files
and reference them with a <code>src=’path_to_file.js’</code> attribute.
</p>
<p>
Similarly, inline event handlers,
which are a common occurrence and convenience feature
used by many Web developers, will not execute.
For example, consider common instances such as:
</p>
<pre>
&lt;body onload="initialize()">
&lt;button onclick="handleClick()" id="button1">
</pre>
<p>
These will not work in manifest V2 extensions.
Remove the inline event handlers,
place them in your external JS file and use <code>addEventListener()</code>
to register event handlers for them instead.
For example, in your JS code, use:
</p>
<pre>
window.addEventListener("load", initialize);
...
document.getElementById("button1").addEventListener("click",handleClick);
</pre>
<p>
This is a much cleaner way of separating
your extension’s behavior from its user interface markup.
</p>
<h3 id="embedding">Embedding content</h3>
<p>
There are some scenarios where your extension might embed content
that can be used externally or come from an external source.
</p>
<p>
<strong>Extension content in web pages:</strong><br>
If your extension embeds resources (like images, script, CSS styles, etc)
that are used in content scripts that are injected into web pages,
you need to use the
<a href="manifest/web_accessible_resources.html">web_accessible_resources</a> property
to whitelist these resources so that external Web pages can use them:
</p>
<pre>
{ // manifest file
...
"<strong>web_accessible_resources</strong>": [
"images/image1.png",
"script/myscript.js"
],
...
}
</pre>
<p>
<strong>Embedding external content:</strong><br>
The Content Security Policy only allows local script
and objects to loaded from your package,
which prevents external attackers from introducing unknown code to your extension.
However, there are times when you want to load externally served resources,
such as jQuery or Google Analytics code.
There are two ways to do this:
</p>
<ol>
<li>Download the relevant library locally (like jQuery)
and package it with your extension.</li>
<li>You can relax the CSP in a limited way by whitelisting HTTPS origins
in the “content_security_policy” section of your manifest.
To include a library like Google Analytics, this is the approach to take:
<pre>
{ // manifest file
...,
"content_security_policy": "script-src 'self'
<strong>https://ssl.google-analytics.com</strong>; object-src 'self'",
...
}
</pre></li>
</ol>
<h3 id="using">Using dynamic script evaluation</h3>
<p>
Perhaps one of the biggest changes in the new manifest v2 scheme is
that extensions can no longer use dynamic script evaluation techniques like
<code>eval()</code> or new <code>Function()</code>,
or pass strings of JS code to functions
that will cause an <code>eval()</code> to be used,
like <code>setTimeout()</code>.
In addition, certain commonly used JavaScript libraries,
such as Google Maps and certain templating libraries,
are known to use some of these techniques.
</p>
<p>
Chrome provides a sandbox for pages to run in their own origin,
which are denied access to chrome.* APIs.
In order to use <code>eval()</code>
and the like under the new Content Security Policy:
</p>
<ol>
<li>Create a sandbox entry in your manifest file.</li>
<li>In the sandbox entry,
list the pages you want to run in the sandbox.</li>
<li>Use message passing via <code>postMessage()</code>
to communicate with the sandboxed page.</li>
</ol>
<p>
For more details on how to do this,
see the <a href="sandboxingEval.html">Sandboxing Eval</a> documentation.
</p>
<h2 id="further-reading">Further reading</h2>
<p>
The changes in manifest version 2 are designed to guide developers
toward building more secure and robustly-architected extensions and apps.
To see a complete list of changes from manifest version 1 to version 2,
see the <a href="manifestVersion.html">manifest file</a> documentation.
For more information about using sandboxing to isolate unsafe code,
read the <a href="sandboxingEval.html">sandboxing eval</a> article.
You can learn more about Content Security Policy
by visiting our extensions-related tutorial and a
<a href="http://www.html5rocks.com/en/tutorials/security/content-security-policy/">good introduction on HTML5Rocks</a>.
</p>