{"id":1421,"date":"2019-01-25T01:58:14","date_gmt":"2019-01-25T01:58:14","guid":{"rendered":"https:\/\/blog.hassler.ec\/wp\/?p=1421"},"modified":"2019-01-06T21:21:44","modified_gmt":"2019-01-06T21:21:44","slug":"features-of-the-chrome-api-you-should-know","status":"publish","type":"post","link":"https:\/\/blog.hassler.ec\/wp\/2019\/01\/25\/features-of-the-chrome-api-you-should-know\/","title":{"rendered":"Features of the Chrome API you should\u00a0know"},"content":{"rendered":"<section class=\"section section--body section--first\">\n<div class=\"section-content\">\n<div class=\"section-inner sectionLayout--insetColumn\">\n<h1 id=\"5383\" class=\"graf graf--h3 graf--leading graf--title\"><img decoding=\"async\" class=\"progressiveMedia-image js-progressiveMedia-image\" style=\"font-size: 14px;\" src=\"https:\/\/cdn-images-1.medium.com\/max\/2000\/0*Got1zk0gpNuHC0V1\" data-src=\"https:\/\/cdn-images-1.medium.com\/max\/2000\/0*Got1zk0gpNuHC0V1\"><\/h1>\n<\/div>\n<div class=\"section-inner sectionLayout--fullWidth\">\n<figure id=\"8a29\" class=\"graf graf--figure graf--layoutFillWidth graf-after--h3\" data-scroll=\"native\"><figcaption class=\"imageCaption\">Photo by&nbsp;<a class=\"markup--anchor markup--figure-anchor\" href=\"https:\/\/unsplash.com\/@jonatanq?utm_source=medium&amp;utm_medium=referral\" target=\"_blank\" rel=\"photo-creator noopener\" data-href=\"https:\/\/unsplash.com\/@jonatanq?utm_source=medium&amp;utm_medium=referral\">Jonatan Quintero<\/a>&nbsp;on&nbsp;<a class=\"markup--anchor markup--figure-anchor\" href=\"https:\/\/unsplash.com\/?utm_source=medium&amp;utm_medium=referral\" target=\"_blank\" rel=\"photo-source noopener\" data-href=\"https:\/\/unsplash.com?utm_source=medium&amp;utm_medium=referral\">Unsplash<\/a><\/figcaption><\/figure>\n<\/div>\n<div class=\"section-inner sectionLayout--insetColumn\">\n<p id=\"b8fd\" class=\"graf graf--p graf-after--figure\">So you think you know your way around building a Chrome extension? Well, that\u2019s all fine and dandy, but have you heard about context menus? Messaging between scripts? Adding a badge to your extension\u2019s icon? If all this sounds fascinating, you\u2019re in luck. We\u2019ll go over some cool features the Chrome API grants us.<\/p>\n<p id=\"34bd\" class=\"graf graf--p graf-after--p\">If you are interested in reading about how to build a Chrome extension, you can read my previous article&nbsp;<a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/medium.freecodecamp.org\/how-to-implement-a-chrome-extension-3802d63b5376\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/medium.freecodecamp.org\/how-to-implement-a-chrome-extension-3802d63b5376\">here<\/a>. If you want to know how to publish one, you can read all about it&nbsp;<a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/medium.freecodecamp.org\/chrome-extension-how-to-publish-dd8400a3d53\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/medium.freecodecamp.org\/chrome-extension-how-to-publish-dd8400a3d53\">here<\/a><\/p>\n<h3 id=\"d53c\" class=\"graf graf--h3 graf-after--p\"><a class=\"markup--anchor markup--h3-anchor\" href=\"https:\/\/developer.chrome.com\/extensions\/contextMenus\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/developer.chrome.com\/extensions\/contextMenus\">Context Menu<\/a><\/h3>\n<p id=\"a9eb\" class=\"graf graf--p graf-after--h3\">To put it simply, the context menu is the menu that appears when you right-click anywhere inside the browser. You can add your Chrome extension to that menu with a few simple steps:<\/p>\n<ol class=\"postList\">\n<li id=\"3680\" class=\"graf graf--li graf-after--p\">Add<strong class=\"markup--strong markup--li-strong\">&nbsp;context-menus<\/strong>&nbsp;to the&nbsp;<strong class=\"markup--strong markup--li-strong\">permissions<\/strong>&nbsp;key in the manifest<\/li>\n<li id=\"8df1\" class=\"graf graf--li graf-after--li\">Add a 16&#215;16 icon (as it will be used in the context menu)<\/li>\n<li id=\"9301\" class=\"graf graf--li graf-after--li\">Add the following code to your background script:<\/li>\n<\/ol>\n<figure id=\"7dbf\" class=\"graf graf--figure graf--iframe graf-after--li\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\">\n<pre>\/\/An object representing what will be added to the context menu\nvar contextMenuItem = {                      \n\t\"id\": \"ExtensionName\",\n\t\"title\": \"Text that will appear in the context menu\",\n\t\"contexts\": [\"selection\"]\n};\n\n\/\/...\n\/\/ This will add the above object to the context menu\nchrome.contextMenus.create(contextMenuItem);  \n\n\/\/...\n\/\/Adding a listener for clicks\nchrome.contextMenus.onClicked.addListener(function(clickData) {         \n\tif (clickData.menuItemId === \"ExtensionName\" &amp;&amp; clickData.selectionText) {\n\t\t\n\t}\n});<\/pre>\n<\/div>\n<\/div>\n<\/figure>\n<h3 id=\"ea95\" class=\"graf graf--h3 graf-after--figure\"><a class=\"markup--anchor markup--h3-anchor\" href=\"https:\/\/developer.chrome.com\/extensions\/storage\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/developer.chrome.com\/extensions\/storage\">Storage<\/a><\/h3>\n<p id=\"33dc\" class=\"graf graf--p graf-after--h3\">Similar to&nbsp;<a class=\"markup--anchor markup--p-anchor\" href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Web_Storage_API#localStorage\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/API\/Web_Storage_API#localStorage\">localStorage<\/a>, the Chrome API allows saving data as objects, which persists even when the browser is closed and reopened. Here are the necessary steps to allow storage usage in your extension:<\/p>\n<ol class=\"postList\">\n<li id=\"f6b0\" class=\"graf graf--li graf-after--p\">Add<strong class=\"markup--strong markup--li-strong\">&nbsp;storage&nbsp;<\/strong>to the&nbsp;<strong class=\"markup--strong markup--li-strong\">permissions<\/strong>&nbsp;key in the manifest<\/li>\n<li id=\"cd71\" class=\"graf graf--li graf-after--li\">To put data in the storage, you use:<\/li>\n<\/ol>\n<figure id=\"8580\" class=\"graf graf--figure graf--iframe graf-after--li\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\">\n<pre>chrome.storage.local.set({key: value}, function() {\n          \/\/Logic that happens after the data is set\n});<\/pre>\n<\/div>\n<\/div>\n<\/figure>\n<p id=\"aea4\" class=\"graf graf--p graf-after--figure\">3. To pull data from the storage you use:<\/p>\n<figure id=\"af38\" class=\"graf graf--figure graf--iframe graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\">\n<pre>chrome.storage.local.get(['key'], function(result) {\n             \/\/Logic that happens after the data is pulled from the storage \n             \/\/You can find it in result.key and result.value\n});<\/pre>\n<\/div>\n<\/div>\n<\/figure>\n<blockquote id=\"830e\" class=\"graf graf--blockquote graf-after--figure\"><p>\u26a0\ufe0f Do NOT put sensitive user data in the storage since it is not encrypted<\/p><\/blockquote>\n<h3 id=\"4648\" class=\"graf graf--h3 graf-after--blockquote\"><a class=\"markup--anchor markup--h3-anchor\" href=\"https:\/\/developer.chrome.com\/extensions\/messaging#simple\" target=\"_blank\" rel=\"noopener\" data-href=\"https:\/\/developer.chrome.com\/extensions\/messaging#simple\">Messaging<\/a><\/h3>\n<p id=\"97a0\" class=\"graf graf--p graf-after--h3\">Chrome has another nifty feature which lets you pass messages along between scripts. For example, in your extension, you have your popup.js file that deals with things related to the popup window and you have a background script. If you wanted to have those two scripts communicate with each other you could use the following methods:<\/p>\n<p id=\"98a3\" class=\"graf graf--p graf-after--p\"><strong class=\"markup--strong markup--p-strong\">SendMessage<\/strong><\/p>\n<figure id=\"c8c7\" class=\"graf graf--figure graf--iframe graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\">\n<pre>chrome.runtime.sendMessage({\n    data:\"Hello World!\"\n    }, function(response) {\n      \/\/Logic to handle response from object receiving message\n    });<\/pre>\n<\/div>\n<\/div>\n<\/figure>\n<p id=\"cc57\" class=\"graf graf--p graf-after--figure\"><strong class=\"markup--strong markup--p-strong\">Listen In On Incoming Messages<\/strong><\/p>\n<figure id=\"fbd6\" class=\"graf graf--figure graf--iframe graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\">\n<pre>chrome.runtime.onMessage.addListener(function(message,sender,sendResponse){\n\t var str = JSON.stringify(message.data);\n  \/\/Use sendResponse to send a message back to the original sender\n  sendResponse({response: \"Hello back\"});\n});<\/pre>\n<\/div>\n<\/div>\n<\/figure>\n<h3 id=\"ac79\" class=\"graf graf--h3 graf-after--figure\">Badges<\/h3>\n<p id=\"7d75\" class=\"graf graf--p graf-after--h3\">You know them, you love them, and you can add them to the icon of your extension. Make sure to be aware that due to its small size, the text you want to display is limited to&nbsp;<strong class=\"markup--strong markup--p-strong\"><em class=\"markup--em markup--p-em\">four characters<\/em><\/strong>.<\/p>\n<p id=\"42a2\" class=\"graf graf--p graf-after--p\">To set the background color of the badge you use:<\/p>\n<figure id=\"2d0a\" class=\"graf graf--figure graf--iframe graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\">\n<pre>chrome.browserAction.setBadgeBackgroundColor({ color: \"HEXADECIMAL_COLOR\"}, callback);<\/pre>\n<\/div>\n<\/div>\n<\/figure>\n<p id=\"4b32\" class=\"graf graf--p graf-after--figure\">To set the text of the badge you use:<\/p>\n<figure id=\"a94c\" class=\"graf graf--figure graf--iframe graf-after--p\">\n<div class=\"aspectRatioPlaceholder is-locked\">\n<div class=\"aspectRatioPlaceholder-fill\">\n<pre>chrome.browserAction.setBadgeText(object details, function callback)<\/pre>\n<\/div>\n<\/div>\n<\/figure>\n<p id=\"309d\" class=\"graf graf--p graf-after--figure graf--trailing\">In both methods, the callback is an optional parameter you can use after the method finishes its action.<\/p>\n<\/div>\n<\/div>\n<\/section>\n<section class=\"section section--body section--last\">\n<div class=\"section-divider\">\n<hr class=\"section-divider\">\n<\/div>\n<div class=\"section-content\">\n<div class=\"section-inner sectionLayout--insetColumn\">\n<p id=\"ad9a\" class=\"graf graf--p graf--leading\">Have other Chrome APIs you want to know about? Want to ask something? Feel free to reach out.<\/p>\n<p id=\"3b65\" class=\"graf graf--p graf-after--p graf--trailing\"><em class=\"markup--em markup--p-em\">If you liked this article, clap away so that others can enjoy it as well! ?<\/em><\/p>\n<\/div>\n<\/div>\n<\/section>\n<p>&nbsp;<\/p>\n<p>Source:<\/p>\n<p>Written by<\/p>\n<div class=\"u-tableCell\"><a class=\"link u-baseColor--link avatar\" dir=\"auto\" title=\"Go to the profile of tomerpacific\" href=\"https:\/\/medium.freecodecamp.org\/@tomerpacific?source=footer_card\" aria-label=\"Go to the profile of tomerpacific\" data-action-source=\"footer_card\" data-user-id=\"e97020a2a53f\" data-collection-slug=\"free-code-camp\"><img decoding=\"async\" class=\"avatar-image avatar-image--small alignleft\" src=\"https:\/\/cdn-images-1.medium.com\/fit\/c\/60\/60\/1*tRCMEre0zzKkBWlHDJNbGw.jpeg\" alt=\"Go to the profile of tomerpacific\"><\/a><\/div>\n<div class=\"u-tableCell u-verticalAlignMiddle u-breakWord u-paddingLeft15\">\n<h3 class=\"ui-h3 u-fontSize18 u-lineHeightTighter u-marginBottom4\"><a class=\"link link--primary u-accentColor--hoverTextNormal\" dir=\"auto\" title=\"Go to the profile of tomerpacific\" href=\"https:\/\/medium.freecodecamp.org\/@tomerpacific\" rel=\"author cc:attributionUrl\" aria-label=\"Go to the profile of tomerpacific\" data-user-id=\"e97020a2a53f\" data-collection-slug=\"free-code-camp\">tomerpacific<\/a><\/h3>\n<\/div>\n<p>&nbsp;<\/p>\n<div class=\"u-tableCell \"><a class=\"link u-baseColor--link avatar avatar--roundedRectangle\" title=\"Go to freeCodeCamp.org\" href=\"https:\/\/medium.freecodecamp.org\/?source=footer_card\" aria-label=\"Go to freeCodeCamp.org\" data-action-source=\"footer_card\" data-collection-slug=\"free-code-camp\"><img decoding=\"async\" class=\"avatar-image u-size60x60 alignleft\" src=\"https:\/\/cdn-images-1.medium.com\/fit\/c\/60\/60\/1*MotlWcSa2n6FrOx3ul89kw.png\" alt=\"freeCodeCamp.org\"><\/a><\/div>\n<div class=\"u-tableCell u-verticalAlignMiddle u-breakWord u-paddingLeft15\">\n<h3 class=\"ui-h3 u-fontSize18 u-lineHeightTighter u-marginBottom4\"><a class=\"link link--primary u-accentColor--hoverTextNormal\" href=\"https:\/\/medium.freecodecamp.org\/?source=footer_card\" rel=\"collection\" data-action-source=\"footer_card\" data-collection-slug=\"free-code-camp\">freeCodeCamp.org<\/a><\/h3>\n<p class=\"ui-body u-fontSize14 u-lineHeightBaseSans u-textColorDark u-marginBottom4\">Stories worth reading about programming and technology from our open source community.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Photo by&nbsp;Jonatan Quintero&nbsp;on&nbsp;Unsplash So you think you know your way around building a Chrome extension? Well, that\u2019s all fine and [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":1423,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[12,70,71,77,48,78,118,47],"tags":[],"class_list":["post-1421","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-bloghassler-ec","category-chrome","category-chrome-devtools","category-chromebook","category-front-end","category-google","category-internet","category-medium"],"_links":{"self":[{"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/posts\/1421","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/comments?post=1421"}],"version-history":[{"count":2,"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/posts\/1421\/revisions"}],"predecessor-version":[{"id":1425,"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/posts\/1421\/revisions\/1425"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/media\/1423"}],"wp:attachment":[{"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/media?parent=1421"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/categories?post=1421"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.hassler.ec\/wp\/wp-json\/wp\/v2\/tags?post=1421"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}