| <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 <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 <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> |
| <html> |
| <head> |
| <script> |
| function myFunc() { ... } |
| </script> |
| </head> |
| </html> |
| </pre> |
| |
| <p> |
| This code would cause an error at runtime. |
| To fix this, move <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> |
| <body onload="initialize()"> |
| <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> |
| |
| |
| |
| |