Understand the data communication in a Chrome extension with a side panel.
Style: guided
Overview
Side panels are really useful to create a fully independent DOM for your Chrome extension. But they can be tricky to manage. In this workshop, we'll explore how you can reliably exchange data between the side panel and the content via the service worker.
You will:
- Use the People and Code extension builder
- Manage the state of the side panel
- Understand the different contexts of an extension
- Establish reliable communication between the contexts of the extension
- Call an external API from an extension
Exercises
-
Create an extension boilerplate
- Clone and set up the People and Code Chrome extension generator
- Create an extension with side panel named ‘My Dictionary’ (name the directory in kebab-case)
- Follow the instructions on screen and open the code in VS Code (see the repo README for detailed instructions)
- Explore the code, here are some guiding questions:
- What coding tools are used and how are they setup?
- What does the
support
directory contain? - Where is the extension code located?
- What permissions are declared in the manifest? What are they for? (Extension permission list)
- What are the different extension contexts and how are they segregated?
- What are the coding differences between the contexts (e.g. declaration in the manifest, coding style)?
- Load the extension locally on your Chromium browser (see the repo README for detailed instructions), and run it as is. Open the different consoles and get a feel for how the code works in practice. Look out for the management of the side panel state. What happens when you follow a link in the same tab? When you change tabs?
Congratulations! You now have your own local extension.
-
Explore communication between the contexts
We'll now start to build the dictionary functionality in the extension. First we'll create a context menu in the main page:
-
In the service worker, create an entry in the context menu using the chrome.contextMenus API. Use the following
CreateProperties
objects as input:{ id: 'my-dictionary', contexts: ['selection'], title: 'Meaning of "%s"', }
Wrap it with a
chrome.runtime.onInstalled
event listener to install the context menu entry only once.Try it out. Do you get an error in the extension console? Have we forgotten something?
-
Let's pass the selected word to the side panel. Add an event listener for the
chrome.contextMenus.onClicked
action. The callback takes 2 arguments:-
info
: Information sent when a context menu item is clicked. We'll use themenuItemId
and theselectionText
properties -
tab
: Information about the tab (we'll use it later)
Get the callback to only process the selected word when the
my-dictionary
menu item is selected.To pass the selected text to the side panel, a few things have to happen:
- Make sure the side panel is open. Check the event listener for
chrome.action.onClicked
for hints. Remember to handle the local cache afterwards otherwisechrome.sidePanel.open
won't work. -
Send the word to the side panel using
chrome.runtime.sendMessage
with just a message object. Use the following template (we'll expand it with the definition in the next section):{ from: 'service-worker', action: 'send-definition', word: // the selected word }
Try the context menu, the side panel should open and its console should tell you it received a message.
-
In the side panel, handle the message to display the word inside the
div#message
element.
-
-
-
Call an external API and display the results
In this section, we will call the Dictionary API, display the results, and highlight the word in the DOM to illustrate that communication aspect.
- Before sending the word to the API, turn it into lower case and trim any spaces
- Use the
fetch
API asynchronously to get the Dictionary API response. Do we need extra permissions to call an external API? - Use the json() method asynchronously to extract a JSON version of the API response.
- Send the result to the side panel in a new field with key `definition`
- Display the full API response in the side panel using
JSON.stringify()
. Use the side panel CSS to make it as fancy as you like. -
In the main window, we'd like to get a simple feedback of whether a definition has been found. Maybe a highlight or anything that you'd find relevant.
To feedback that, you can send a message using the
chrome.tabs.sendMessage
method in the service worker. Check thecloseSidePanel
andhandlePanelOpening
functions for inspiration and handle your message in the content script.Tip: Remember to reload your page after reloading your extension when working with content scripts!
Summary
To build a Chrome extension, you need to pay attention to a few important details:
- Declare the appropriate permissions for the actions you want to accomplish
- Be aware of the different contexts (content, service worker and side panel) and how to communicate effectively between them
- Manage the state of the side panel and its reaction to user actions in the content
- Make sure the browser has the latest version loaded and the content scripts are updated
Using the People and Code extension generator can help you get the basics sorted. After that, it's a matter of experimenting.
Supporting materials
Further reading
Once you're happy with your extension, you can share it on the Chrome Web Store. We wrote a simple tutorial on how to build and distribute a Chrome extension.