{"id":1354,"date":"2024-01-30T20:30:08","date_gmt":"2024-01-30T19:30:08","guid":{"rendered":"https:\/\/www.stefanvd.net\/blog\/?p=1354"},"modified":"2024-04-28T13:58:16","modified_gmt":"2024-04-28T12:58:16","slug":"build-web-browser-side-panel","status":"publish","type":"post","link":"https:\/\/www.stefanvd.net\/blog\/2024\/01\/30\/build-web-browser-side-panel\/","title":{"rendered":"Build a Web Browser Side Panel Browser Extension with Manifest V3"},"content":{"rendered":"\n<div class=\"wp-block-rank-math-toc-block\" id=\"rank-math-toc\"><p>Table of Contents<\/p><nav><ul><li><a href=\"#introduction\">Introduction<\/a><\/li><li><a href=\"#create-a-side-panel-and-sidebar-browser-extension\">Create a Side Panel and Sidebar Browser Extension<\/a><ul><li><a href=\"#development-of-your-side-panel\">Development of your Side Panel<\/a><ul><li><a href=\"#google-chrome-code-version\">Google Chrome code version<\/a><\/li><li><a href=\"#firefox-code-version\">Firefox code version<\/a><\/li><\/ul><\/li><li><a href=\"#full-open-source-code\">Full Open-Source code<\/a><\/li><\/ul><\/li><li><a href=\"#what-browser-vendors-need-to-do-for-users-and-developers\">What browser vendors need to do for users and developers<\/a><ul><li><a href=\"#for-users\">For Users<\/a><\/li><li><a href=\"#for-developers\">For Developers<\/a><\/li><\/ul><\/li><li><a href=\"#addition-resource\">Addition resource<\/a><\/li><li><a href=\"#conclusion\">Conclusion<\/a><\/li><\/ul><\/nav><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"introduction\">Introduction<\/h2>\n\n\n\n<p>A few days ago, I launched my new <a href=\"https:\/\/chromewebstore.google.com\/detail\/page-sidebar-open-any-pag\/gkkebamcfeaggmcfciekfakbmlgckdnh\" target=\"_blank\" rel=\"noreferrer noopener\">Page Sidebar browser extension<\/a>, which is available for Google Chrome, Firefox, and Microsoft Edge. The browser extension enables users to open any website in a side panel. And where you can drag anything on the side panel page. Such as a hyperlink or selected text. And instantly show it in the panel. The Page Sidebar browser extension is free and open-source, allowing users and developers to learn how to write such a useful tool for users around the world.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Use the&nbsp;<code>chrome.sidePanel<\/code>&nbsp;API to host content in the browser&#8217;s side panel alongside the main content of a webpage.<\/p>\n<cite><a href=\"https:\/\/developer.chrome.com\/docs\/extensions\/reference\/api\/sidePanel\" target=\"_blank\" rel=\"noreferrer noopener\">Chrome developer documentation page<\/a><\/cite><\/blockquote>\n\n\n\n<p>In this developer article, I delve into my experience with developing Side Panel extensions and the challenges encountered in ensuring compatibility across major web browsers such as Google Chrome, Firefox, and Microsoft Edge. Thereby I will give you an overview of what I have learned. But first how beginner developers like yourself can create high-quality browser extensions with any website content (YouTube, Facebook, Reddit, etc.) in a side panel.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"598\" src=\"https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/google-chrome-side-panel-chrome-extension-1024x598.png\" alt=\"Google Chrome Side Panel open on the Extension Developer Documentation\" class=\"wp-image-1389\" srcset=\"https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/google-chrome-side-panel-chrome-extension-1024x598.png 1024w, https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/google-chrome-side-panel-chrome-extension-300x175.png 300w, https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/google-chrome-side-panel-chrome-extension-768x448.png 768w, https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/google-chrome-side-panel-chrome-extension-1536x896.png 1536w, https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/google-chrome-side-panel-chrome-extension-2048x1195.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Google Chrome Side Panel open on the Extension Developer Documentation<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"create-a-side-panel-and-sidebar-browser-extension\">Create a Side Panel and Sidebar Browser Extension<\/h2>\n\n\n\n<p>Building a side panel presents challenges, especially since each web browser structures the sidebar differently. In Opera and Firefox is it called Sidebar. In Google Chrome, it is referred to as a side panel. Furthermore, the Safari web browser does not currently support this feature, though this status may change in the upcoming Apple WWDC 2024. The developer conference to announce software updates for macOS, iOS, and iPadOS.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"development-of-your-side-panel\">Development of your Side Panel<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"google-chrome-code-version\">Google Chrome code version<\/h4>\n\n\n\n<p>When you want to load a website in the side panel of the Chrome web browser. The first step is to make sure you are using the latest Manifest V3 technology version. That has improvement in performance, privacy, and security. Thereby, to enable the display of all websites in the panel, utilize the &#8220;host_permissions&#8221; and set it to include all websites.<\/p>\n\n\n\n<p>This is how the &#8220;manifest.json&#8221; file should look:<\/p>\n\n\n\n<p><strong>Manifest.json<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"manifest_version\": 3,\n  \"name\": \"__MSG_namefull__\",\n  \"short_name\": \"__MSG_name__\",\n  \"description\": \"__MSG_description__\",\n  \"version\": \"1.0.2\",\n  \"background\": {\n    \"service_worker\": \"scripts\/background.js\"\n  },\n  \"host_permissions\": &#91; \"&lt;all_urls&gt;\" ],\n  \"icons\": {\n    \"16\": \"images\/icon16.png\",\n    \"24\": \"images\/icon24.png\",\n    \"32\": \"images\/icon32.png\",\n    \"48\": \"images\/icon48.png\",\n    \"96\": \"images\/icon96.png\",\n    \"128\": \"images\/icon128.png\"\n  },\n  \"default_locale\": \"en\",\n  \"side_panel\": {\n    \"default_path\": \"panel.html\"\n  },\n  \"action\": {\n    \"default_title\": \"__MSG_name__\"\n  },\n  \"options_ui\": {\n    \"page\": \"options.html\",\n    \"open_in_tab\": true\n  },\n  \"offline_enabled\": true,\n  \"minimum_chrome_version\": \"114\",\n  \"permissions\": &#91;\"contextMenus\", \"storage\", \"sidePanel\", \"declarativeNetRequestWithHostAccess\"]\n}<\/code><\/pre>\n\n\n\n<p>Note that there is a limit in the Google Chrome web browser, and that is that you can not switch the panel to left or right. There is only the right side to open and close the panel.<\/p>\n\n\n\n<p><strong>Background.js<\/strong><\/p>\n\n\n\n<p>In the &#8220;Background.js&#8221; file, utilize this code to ensure that clicking the button will open your side panel.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>chrome.sidePanel.setPanelBehavior({openPanelOnActionClick: true}).catch((error) =&gt; console.error(error));<\/code><\/pre>\n\n\n\n<p><strong>Panel.html<\/strong><\/p>\n\n\n\n<p>Now add a &#8220;panel.html&#8221; file in your Chrome extension. This iframe element will be used to show any websites in your side panel. That can be a YouTube video, Google News website, X, Reddit, etc.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;iframe id=\"preview\" class=\"stefanvdpagesidebar\" allow=\"camera; clipboard-write; fullscreen; microphone; geolocation\"&gt;&lt;\/iframe&gt;<\/code><\/pre>\n\n\n\n<p>The &#8220;allow&#8221; attribute is required to enable access to hardware and allow copying to the clipboard in your iframe web browser for websites such as Google Search, YouTube, Telegram, etc.<\/p>\n\n\n\n<p><strong>Panel.js<\/strong><\/p>\n\n\n\n<p>Lastly, your &#8220;panel.js&#8221; script file enables the display of any website. To allow us to see any websites we need to adjust the frame. If we use no chrome.declarativeNetRequest then it results in a blocked website by anchor frame. As you can see in the screenshot here below:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"598\" src=\"https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/google-chrome-sidepanel-error-refused-to-connect-1024x598.png\" alt=\"Error message www.google.com refused to connect in the side panel\" class=\"wp-image-1411\" srcset=\"https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/google-chrome-sidepanel-error-refused-to-connect-1024x598.png 1024w, https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/google-chrome-sidepanel-error-refused-to-connect-300x175.png 300w, https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/google-chrome-sidepanel-error-refused-to-connect-768x449.png 768w, https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/google-chrome-sidepanel-error-refused-to-connect-1536x897.png 1536w, https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/google-chrome-sidepanel-error-refused-to-connect-2048x1196.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Error message www.google.com refused to connect in the side panel<\/figcaption><\/figure>\n\n\n\n<p>Use this code, this code is designed to remove specific security-related headers from the response of network requests made by the browser, particularly affecting iframes with the ID &#8220;preview&#8221; on any page. This is to bypass certain security restrictions related to framing content from different domains. That is thanks to the powerful chrome.declarativeNetRequest API.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>const open = async(currenturl) =&gt; {\n\tconst iframe = document.getElementById(\"preview\");\n\tawait chrome.declarativeNetRequest.updateSessionRules({\n\t\tremoveRuleIds: &#91;1],\n\t\taddRules: &#91;{\n\t\t\tid: 1,\n\t\t\tpriority: 1,\n\t\t\taction: {\n\t\t\t\ttype: \"modifyHeaders\",\n\t\t\t\tresponseHeaders: &#91;\n\t\t\t\t\t{header: \"x-frame-options\", operation: \"remove\"},\n\t\t\t\t\t{header: \"content-security-policy\", operation: \"remove\"},\n\t\t\t\t],\n\t\t\t},\n\t\t\tcondition: {\n\t\t\t\turlFilter: \"*\",\n\t\t\t\tresourceTypes: &#91;\"main_frame\", \"sub_frame\", \"xmlhttprequest\", \"websocket\"],\n\t\t\t},\n\t\t},\n\t\t],\n\t});\n};<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"firefox-code-version\">Firefox code version<\/h4>\n\n\n\n<p>In Firefox, the sidebar operates differently as it does not require additional permission in the Manifest file. And can contain the same background and panel script files.<\/p>\n\n\n\n<p><strong>Manifest.json<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"manifest_version\": 3,\n  \"name\": \"__MSG_namefull__\",\n  \"short_name\": \"__MSG_name__\",\n  \"description\": \"__MSG_description__\",\n  \"version\": \"1.0.2\",\n  \"background\": {\n    \"scripts\": &#91;\"scripts\/constants.js\",\"scripts\/background.js\"]\n  },\n  \"host_permissions\": &#91; \"*:\/\/*\/*\" ],\n  \"icons\": {\n    \"16\": \"images\/icon16.png\",\n    \"24\": \"images\/icon24.png\",\n    \"32\": \"images\/icon32.png\",\n    \"48\": \"images\/icon48.png\",\n    \"96\": \"images\/icon96.png\",\n    \"128\": \"images\/icon128.png\"\n  },\n  \"default_locale\": \"en\",\n  \"sidebar_action\": {\n    \"default_icon\": {\n      \"16\": \"images\/icon16.png\",\n      \"32\": \"images\/icon32.png\"\n    },\n    \"default_title\": \"__MSG_name__\",\n    \"default_panel\": \"panel.html\",\n    \"open_at_install\":true\n  },\n  \"action\": {\n    \"default_icon\": {\n      \"16\": \"images\/icon16.png\",\n      \"32\": \"images\/icon32.png\"\n    },\n    \"default_title\": \"__MSG_name__\"\n  },\n  \"options_ui\": {\n    \"page\": \"options.html\",\n    \"open_in_tab\": true\n  },\n  \"permissions\": &#91;\"contextMenus\", \"storage\", \"declarativeNetRequestWithHostAccess\"],\n  \"browser_specific_settings\": {\n    \"gecko\": {\n        \"id\": \"pagesidebar@stefanvd.net\",\n        \"strict_min_version\": \"113.0\"\n    }\n  }\n}<\/code><\/pre>\n\n\n\n<p>What is useful for the user if they use the Firefox web browser, is that you can choose which side you want the sidebar must be visible. That is on the left or the right side.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"487\" height=\"1024\" src=\"https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/move-firefox-sidebar-to-left-or-right-487x1024.png\" alt=\"Firefox Sidebar to Left or Right\" class=\"wp-image-1384\" srcset=\"https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/move-firefox-sidebar-to-left-or-right-487x1024.png 487w, https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/move-firefox-sidebar-to-left-or-right-143x300.png 143w, https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/move-firefox-sidebar-to-left-or-right-768x1615.png 768w, https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/move-firefox-sidebar-to-left-or-right-731x1536.png 731w, https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/move-firefox-sidebar-to-left-or-right-974x2048.png 974w, https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/move-firefox-sidebar-to-left-or-right.png 994w\" sizes=\"(max-width: 487px) 100vw, 487px\" \/><figcaption class=\"wp-element-caption\">Firefox Sidebar to Left or Right<\/figcaption><\/figure>\n\n\n\n<p><strong>Access your data for all websites<\/strong><\/p>\n\n\n\n<p>Here comes the difficulty with Firefox, which differs from Chrome extensions. Firefox does not allow the automatic display of the website content for all websites; it blocks this as default permission (when using the Manifest V3). Users need to manually grant permission on their <strong>Add-on page<\/strong> and toggle the <strong>switch <\/strong>to enable it.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"500\" src=\"https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/firefox-sidebar-access-your-data-for-all-websites-1024x500.png\" alt=\"Firefox Access your data for all websites permission\" class=\"wp-image-1386\" srcset=\"https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/firefox-sidebar-access-your-data-for-all-websites-1024x500.png 1024w, https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/firefox-sidebar-access-your-data-for-all-websites-300x146.png 300w, https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/firefox-sidebar-access-your-data-for-all-websites-768x375.png 768w, https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/firefox-sidebar-access-your-data-for-all-websites-1536x749.png 1536w, https:\/\/www.stefanvd.net\/blog\/wp-content\/uploads\/2024\/01\/firefox-sidebar-access-your-data-for-all-websites-2048x999.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Firefox Access your data for all websites&#8217; permission<\/figcaption><\/figure>\n\n\n\n<p>Another option to improve this user experience is to detect it using the browser permission API. Then, when the user clicks on the button of your sidebar extension, prompt them to allow adding <code>\"*<em>:\/<\/em>\/*\/*\"<\/code>. As you can see in the below code example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>browser.permissions.contains({\n\t\t\torigins: &#91;\"*:\/\/*\/*\"]\n\t\t}, (result) =&gt; {\n\t\t\tif(result){\n\t\t\t\t\/\/ The extension has the permissions.\n\t\t\t\tchrome.tabs.sendMessage(sender.tab.id, {text: \"receiveallhost\", value: result});\n\t\t\t}else{\n\t\t\t\t\/\/ The extension does not have the permissions\n\t\t\t\tchrome.tabs.sendMessage(sender.tab.id, {text: \"receiveallhost\", value: result});\n\t\t\t}\n\t\t});<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"full-open-source-code\">Full Open-Source code<\/h3>\n\n\n\n<p>I have developed two Side Panel browser extensions which are presently accessible in the Extension Gallery. Both browser extensions, namely Note Sidebar and Page Sidebar, are freely available and Open-Source. As a developer or user, you have the opportunity to examine the code, initiate the process immediately, and engage in testing and constructing your initial browser extension.<\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/stefanvd\/Browser-Extensions\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub Browser Extension Code<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"what-browser-vendors-need-to-do-for-users-and-developers\">What browser vendors need to do for users and developers<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"for-users\">For Users<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Google Chrome, should provide an option to choose which side panel can be visible (left and right).<\/li>\n\n\n\n<li>Have a pinned shortcut on the side panel, that opens that specific extension panel.<\/li>\n\n\n\n<li>The permission &#8220;Access your data for all websites&#8221; in Firefox should not be disabled for the user. As the user already provided permission during the initial installation to either allow or not allow the installation of this Firefox extension.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"for-developers\">For Developers<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>There should be consistent permission requirements for harmony in browser extension development. Currently, one web browser requires permission <code>\"sidePanel\"<\/code> to open a side panel, while the other does not.<\/li>\n\n\n\n<li>Reduce the code without using the <code>chrome.declarativeNetRequest<\/code> API<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"addition-resource\">Addition resource <\/h2>\n\n\n\n<p>To further explore the Side Panel Manifest V3 and the Sidebar APIs and advance in crafting innovative experiences for users, please refer to the following resources:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/groups.google.com\/a\/chromium.org\/g\/chromium-extensions?hl=en\" target=\"_blank\" rel=\"noreferrer noopener\">Chromium Extension group<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/developer.chrome.com\/docs\/extensions\/reference\/api\/sidePanel\" target=\"_blank\" rel=\"noreferrer noopener\">Chrome for Developers &#8211; Side Panel API documentation<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Mozilla\/Add-ons\/WebExtensions\/user_interface\/Sidebars\" target=\"_blank\" rel=\"noreferrer noopener\">Firefox Sidebars API<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"conclusion\">Conclusion<\/h2>\n\n\n\n<p>I hope you learn something new in this informative guide, particularly in creating a robust Side Panel Chrome extension using Manifest V3, especially for beginner developers. Now that you have acquainted yourself with the Side panel and its limitations across various web browsers. If you like my open work I share this with the browser extension community. And if you would like to support my work in the web community, please consider <a href=\"https:\/\/www.stefanvd.net\/donate\/\" target=\"_blank\" rel=\"noreferrer noopener\">making a small donation<\/a> to help drive future initiatives and advancements. Your generosity is greatly appreciated.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction A few days ago, I launched my new Page Sidebar browser extension, which is available for Google Chrome, Firefox, and Microsoft Edge. The browser extension enables users to open any website in a side panel. And where you can drag anything on the side panel page. Such as a hyperlink or selected text. And [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1383,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[],"class_list":["post-1354","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programming"],"_links":{"self":[{"href":"https:\/\/www.stefanvd.net\/blog\/wp-json\/wp\/v2\/posts\/1354","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.stefanvd.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.stefanvd.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.stefanvd.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.stefanvd.net\/blog\/wp-json\/wp\/v2\/comments?post=1354"}],"version-history":[{"count":43,"href":"https:\/\/www.stefanvd.net\/blog\/wp-json\/wp\/v2\/posts\/1354\/revisions"}],"predecessor-version":[{"id":1647,"href":"https:\/\/www.stefanvd.net\/blog\/wp-json\/wp\/v2\/posts\/1354\/revisions\/1647"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.stefanvd.net\/blog\/wp-json\/wp\/v2\/media\/1383"}],"wp:attachment":[{"href":"https:\/\/www.stefanvd.net\/blog\/wp-json\/wp\/v2\/media?parent=1354"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.stefanvd.net\/blog\/wp-json\/wp\/v2\/categories?post=1354"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.stefanvd.net\/blog\/wp-json\/wp\/v2\/tags?post=1354"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}