Extend DevTools

DevTools extensions add features to Chrome DevTools by accessing DevTools-specificextension APIs through a DevTools page added to the extension.

Architecture diagram showing DevTools page communicating with the         inspected window and the service worker. The service worker is shown         communicating with the content scripts and accessing extension APIs.         The DevTools page has access to the DevTools APIs, for example, creating panels.
DevTools extension architecture.

The DevTools-specific extension APIs include the following:

The DevTools page

When a DevTools window opens, a DevTools extension creates an instance of its DevTools page thatexists as long as the window is open. This page has access to the DevTools APIs and extension APIs, and can do the following:

The DevTools page can directly access extensions APIs. This includes being ableto communicate with the service worker usingmessage passing.

Create a DevTools extension

To create a DevTools page for your extension, add thedevtools_page field in the extensionmanifest:

{"name":..."version":"1.0","devtools_page":"devtools.html",...}

Thedevtools_page field must point to an HTML page. Because the DevToolspage must be local to your extension, we recommend specifying it using a relative URL.

The members of thechrome.devtools API are available only to the pages loaded within the DevToolswindow while that window is open. Content scripts and other extension pages don't have accessto these APIs.

DevTools UI elements: panels and sidebar panes

In addition to the usual extension UI elements, such as browser actions, context menus and popups, aDevTools extension can add UI elements to the DevTools window:

  • Apanel is a top-level tab, like the Elements, Sources, and Network panels.
  • Asidebar pane presents supplementary UI related to a panel. The Styles, Computed Styles, andEvent Listeners panes on the Elements panel are examples of sidebar panes. Depending on theversion of Chrome you're using and where the DevTools window is docked, your sidebar panes mightlook like the following example image:
DevTools window showing Elements panel and Styles sidebar pane.
DevTools window showing Elements panel and Styles sidebar pane.

Each panel is its own HTML file, which can include other resources (JavaScript, CSS, images, and soon). To create a basic panel, use the following code:

chrome.devtools.panels.create("My Panel","MyPanelIcon.png","Panel.html",function(panel){// code invoked on panel creation});

JavaScript executed in a panel or sidebar pane has access to the same APIs as the DevTools page.

To create a basic sidebar pane, use the following code:

chrome.devtools.panels.elements.createSidebarPane("My Sidebar",function(sidebar){// sidebar initialization code heresidebar.setObject({some_data:"Some data to show"});});

There are several ways to display content in a sidebar pane:

  • HTML content: CallsetPage() to specify an HTML page to display in the pane.
  • JSON data: Pass a JSON object tosetObject().
  • JavaScript expression: Pass an expression tosetExpression(). DevToolsevaluates the expression in the context of the inspected page, then displays the return value.

For bothsetObject() andsetExpression(), the pane displays the value as it would appear in theDevTools console. However,setExpression() lets you display DOM elements and arbitrary JavaScriptobjects, whilesetObject() only supports JSON objects.

Communicate between extension components

The following sections describe some helpful ways to allow DevTools extension components tocommunicate with each other.

Inject a content script

To inject a content script, usescripting.executeScript():

// DevTools page -- devtools.jschrome.scripting.executeScript({target:{tabId:chrome.devtools.inspectedWindow.tabId},files:["content_script.js"]});

You can retrieve the tab ID of the inspected window using theinspectedWindow.tabId property.

If a content script has already been injected, you can use messaging APIs tocommunicate with it.

Evaluate JavaScript in the inspected window

You can use theinspectedWindow.eval() method to execute JavaScriptcode in the context of the inspected page. You can invoke theeval() method from a DevTools page,panel, or sidebar pane.

Caution: Useeval() only if you need access to the JavaScript content of an inspected page. Otherwise,we recommend using thescripting.executeScript() method to run scripts.For more information, seeinspectedWindow.

By default, the expression is evaluated in the context of the main frame of the page.inspectedWindow.eval() uses the same script execution context and options as codeentered in the DevTools console, which allows access to DevToolsConsole UtilitiesAPI features when usingeval(). For example, use it to inspectthe first script element within the<head> section of the HTML document:

chrome.devtools.inspectedWindow.eval("inspect($$('head script')[0])",function(result,isException){});

You can also set theuseContentScriptContext totrue when callinginspectedWindow.eval() toevaluate the expression in the same context as the content scripts. To use this option, use astatic content script declaration before callingeval(), either by callingexecuteScript() or by specifying a contentscript in themanifest.json file. After the context script context loads, you can also use this option toinject additional content scripts.

Pass the selected element to a content script

The content script doesn't have direct access to the current selected element. However, any code youexecute usinginspectedWindow.eval() has access to the DevToolsconsole and Console Utilities APIs. For example, in evaluated code you can use$0 to access theselected element.

To pass the selected element to a content script:

  1. Create a method in the content script that takes the selected element as an argument.

    functionsetSelectedElement(el){// do something with the selected element}
  2. Call the method from the DevTools page usinginspectedWindow.eval()with theuseContentScriptContext: true option.

    chrome.devtools.inspectedWindow.eval("setSelectedElement($0)",{useContentScriptContext:true});

TheuseContentScriptContext: true option specifies that the expression must be evaluated in thesame context as the content scripts, so it can access thesetSelectedElement method.

Get a reference panel'swindow

To callpostMessage() from a devtools panel, you'll need a reference to itswindow object. Get apanel's iframe window from thepanel.onShown event handler:

extensionPanel.onShown.addListener(function(extPanelWindow){extPanelWindowinstanceofWindow;// trueextPanelWindow.postMessage(// …});

Send messages from injected scripts to the DevTools page

Code injected directly into the page without a content script, including by appending a<script>tag or callinginspectedWindow.eval(), can't send messages to theDevTools page usingruntime.sendMessage(). Instead, we recommendcombining your injected script with a content script that can act as an intermediary, and usingthewindow.postMessage() method. The following example uses the background scriptfrom the previous section:

// injected-script.jswindow.postMessage({greeting:'hello there!',source:'my-devtools-extension'},'*');
// content-script.jswindow.addEventListener('message',function(event){// Only accept messages from the same frameif(event.source!==window){return;}varmessage=event.data;// Only accept messages that we know are ours. Note that this is not foolproof// and the page can easily spoof messages if it wants to.if(typeofmessage!=='object'||message===null||message.source!=='my-devtools-extension'){return;}chrome.runtime.sendMessage(message);});

Other alternative message-passing techniques can be foundon GitHub.

Detect when DevTools opens and closes

To track whether the DevTools window is open, add anonConnect listenerto the service worker and callconnect() from the DevTools page. Becauseeach tab can have its own DevTools window open, you might receive multiple connect events.To track whether any DevTools window is open, count the connect and disconnect events as shownin the following example:

// background.jsvaropenCount=0;chrome.runtime.onConnect.addListener(function(port){if(port.name=="devtools-page"){if(openCount==0){alert("DevTools window opening.");}openCount++;port.onDisconnect.addListener(function(port){openCount--;if(openCount==0){alert("Last DevTools window closing.");}});}});

The DevTools page creates a connection like this:

// devtools.js// Create a connection to the service workerconstserviceWorkerConnection=chrome.runtime.connect({name:"devtools-page"});// Send a periodic heartbeat to keep the port open.setInterval(()=>{port.postMessage("heartbeat");},15000);

DevTools extension examples

The examples on this page come from the following pages:

More information

For information on the standard APIs that extensions can use, seechrome.* APIs andwebAPIs.

Give us feedback! Your comments and suggestions help us improve the APIs.

Examples

You can find examples that use DevTools APIs inSamples.

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2012-09-17 UTC.