Safari Extensions

RSS for tag

Enhance and customize the web browsing experience on Mac, iPhone, and iPad with Safari Extensions

Safari Extensions Documentation

Posts under Safari Extensions tag

104 Posts
Sort by:
Post marked as solved
9 Replies
7.6k Views
I am trying to run JavaScript only after the page has loaded, and according to here - https://developer.apple.com/documentation/safariservices/safari_app_extensions/injecting_a_script_into_a_webpage, I should use DOMContentLoaded. However, it does not seem to work. This is my content.js file: function runOnStart() {     document.addEventListener('DOMContentLoaded', function(e) {         document.body.style.background = "rgb(20, 20, 20)";         document.html.style.background = "rgb(20, 20, 20)";                var divElements = document.body.getElementsByTagName('div');         for(var i = 0; i < divElements.length; i++) {             let elem = divElements[i];             elem.style.background = "rgba(255, 255, 255, 0.05)";         }     }); } runOnStart(); If I take the code outside of the event listener, it runs fine, but a lot of the elements haven't loaded in yet so it doesn't work as it should. The function is definitely running, but the event listener simply doesn't work. I appreciate any help you can give!
Posted
by
Post not yet marked as solved
12 Replies
4.7k Views
All of my third party extensions have blue icons now, in Safari 14.0. It looks pretty awful. Is there a way to keep the monochrome colors or a way for us, as developers, to provide a different kind of icon to sustain the monochrome colors for our extensions? I am assuming the blue color denotes something, like the extension being "active". I wasn't able to find documentation on this change nor any related api doc.
Posted
by
Post marked as solved
14 Replies
3.1k Views
Hi folks, We're building a Safari web extension and experiencing an issue to see it among extensions in Safari after installing the container app to /Applications and launching it. The app and extension is notarized and signed with Developer ID After an extensive investigation, we found the following log records in the Console app (the extension ID is redacted): Computing the code signing dictionary failed for extension with identifier com.youcompany.safariext Blocking extension with identifier: com.youcompany.safariext To debug the issue, we've created a HelloWorld-like extension generated by Xcode 12.2 beta 4 (http s://sharedartifacts.s3.eu-central-1.amazonaws.com/safariext.app.zip contains a signed app bundle) It also is under the same code signing issue. According to https://developer.apple.com/documentation/xcode/notarizing_macos_software_before_distribution/resolving_common_notarization_issues, we've run a few checks to verify: code signature ➜&#9;Desktop codesign -vvv --deep --strict ./safariext.app&#9;&#9;&#9;&#9;&#9; ...-prepared:/Users/nikolay/Desktop/safariext.app/Contents/PlugIns/safariext Extension.appex ...-validated:/Users/nikolay/Desktop/safariext.app/Contents/PlugIns/safariext Extension.appex ... ./safariext.app: valid on disk ./safariext.app: satisfies its Designated Requirement signing certificate ➜&#9;Desktop spctl -vvv --assess --type exec ./safariext.app&#9;&#9; ./safariext.app: accepted source=Notarized Developer ID origin=Developer ID secure timestamp ... Timestamp=25 Nov 2020 at 22:23:54 ... We seemed to have all checks good, the extension can be installed only if Safari is allowed to run unsigned extensions. Could anyone assist to debug/resolve this issue? Thanks
Posted
by
Post not yet marked as solved
2 Replies
1.4k Views
My existing chrome extension has "Sign in with Apple" given that we have iOS users. When user clicks "Continue with Apple" button in the extension log in pop up, this is what we do: javascript window.open( 'https://appleid.apple.com/auth/authorize?client_id=' + clientID + '&amp;redirect_uri=' + backEndURL + '&amp;response_type=id_token%20code&amp;response_mode=form_post&amp;scope=email%20name', 'Sign in with Apple', 'height=500,width=400,left=600,top=200,status=no,location=no,toolbar=no,menubar=no' ) In chrome, this opens a popup window with that URL. In Safari Converted Web Extension, it opens custom Apple sign in flow, where it says: "Do you want to sign in to *** with your Apple ID YYY?" and then with my mac password I'm able to authenticate. Afterwards, nothing happens. Expected: a redirect to the URL specified in the window.open. Now let's do a trick: I'll wrap the above window.open code into javascript setTimeout (() = {window.open (...)}, 3000) Because of security reasons, safari then won't open the popup after 3s and will display a notification in the toolbar "Popup blocked..". If we allow the popup, then it finally opens as a normal window popup and after sign in, it redirects to our backend and it successfully authenticates. Any ides what how to solve this? P.S. We're not able to use embedded Sign in with Apple JS - https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/configuring_your_webpage_for_sign_in_with_apple script because we can't host a remote code in the extension (it will be deprecated soon). So, we arere using this. - https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/incorporating_sign_in_with_apple_into_other_platforms
Posted
by
Post not yet marked as solved
3 Replies
1.8k Views
runtime.oninstalled is invoked when I install the extension for the first time in the browser. But if I uninstalled it again (by dragging the app to bin), and tried reinstalling the runtime.oninstalled is not invoked. is that an expected behavior? If so, how can I test this case during extension development? Because it is difficult to find a new browser to test this case every time. Thanks.
Posted
by
Post not yet marked as solved
1 Replies
1.7k Views
I've developed a ios safari web extension for my app and everything seemed to work fine in the simulator and on my device. However, I've noticed that in some cases when the user tries to give permission to the extension inside safari, the system displays an alert asking for permissions to all the sites saved in the user's keychain. It's really strange. I've not been able to always reproduce this behavior, sometimes it works normally and it asks for permission just for the domain where the user is on. The issue has become a real problem when I've discovered that when the user has a lot of saved passwords for sites in the keychain, the Safari freezes when asking for permission and becomes absolutely unusable, forcing the user to close it. Here is the manifest for my extension: { "manifest_version": 2, "content_security_policy": "script-src 'self' https://ssl.google-analytics.com; object-src 'self'", "background": { "scripts": [ "browser-polyfill.js", "background.js" ], "persistent": false }, "content_scripts": [{ "js": [ "browser-polyfill.js", "document-start.js" ], "matches": [ "http://*/*", "https://*/*" ], "run_at": "document_start" }, { "js": [ "browser-polyfill.js", "contentscript.js" ], "matches": [ "http://*/*", "https://*/*" ], "run_at": "document_idle" } ], "browser_action": { "default_icon": { "19": "assets/images/logos/16x16_logo.png", "38": "assets/images/logos/48x48_logo.png", "48": "assets/images/logos/48x48_logo.png", "64": "assets/images/logos/64x64_logo.png", "128": "assets/images/logos/128x128_logo.png", "256": "assets/images/logos/256x256_logo.png", "512": "assets/images/logos/512x512_logo.png" }, "default_popup": "popup.html" }, "icons": { "16": "assets/images/logos/16x16_logo.png", "48": "assets/images/logos/48x48_logo.png", "64": "assets/images/logos/64x64_logo.png", "128": "assets/images/logos/128x128_logo.png", "256": "assets/images/logos/256x256_logo.png", "512": "assets/images/logos/512x512_logo.png" }, "web_accessible_resources": [ "assets/*" ], "permissions": [ "<all_urls>", "cookies", "storage", "unlimitedStorage", "webNavigation", "notifications", "nativeMessaging" ] } Here is the screenshot of the safari asking for permission to the extension to access 653 different websites that are registered in the user's keychain:
Posted
by
Post not yet marked as solved
3 Replies
1.4k Views
I am trying to write a safari web extension that redirects users to Y URL if they type X URL without ever loading the X URL. The piece of code that I have attached below works smoothly on chrome, but not on safari. background.js function onBeforeNavigate(event) { const redirectURL = "https://google.com/" chrome.tabs.update(event.tabId, { url: redirectURL }) } chrome.webNavigation.onBeforeNavigate.addListener(onBeforeNavigate,{ url: [ {urlMatches: "https://girlcodeit.com/*"}, {urlMatches: "http://girlcodeit.com/*"} ] }) manifest.json "manifest_version": 2, "name": "", "description": "", "version": "1.0", "background": { "scripts": [ "background.js" ] }, "permissions": [ "webNavigation", "tabs" ] } I have tried writing browser.tabs.update and just tabs.update in place of chrome.tabs.update in safari version, no change. I want to achieve the redirection anyhow through a safari web extension, please suggest changes in this one or share any other approaches. webRequestBlocking is not supported by Safari, so that doesn't work either.
Posted
by
Post not yet marked as solved
1 Replies
898 Views
Hello, I would like to track the amount of downloads, on Apple Store, of users coming from the Safari Smart Banner. The smart banner is displayed but we don't have any data in Apple Store. How can I track these downloads? We have a campaign link and I've tried three different ways and it didn't work. Thanks. I've tried: <meta name="apple-itunes-app" content="app-id=605512447, affiliate-data=pt=2000418&ct=iOS%20Smart%20Banner&mt=8”/> <meta name="apple-itunes-app" content="app-id=605512447, affiliate-data=pt=2000418&ct=iOS%20Smart%20Banner”/> <meta name="apple-itunes-app" content="app-id=605512447, affiliate-data=ct=iOS%20Smart%20Banner”/>
Posted
by
Post not yet marked as solved
1 Replies
1.1k Views
Hi, According to Blocking Content with Your Safari Web Extension, we can now use the Declarative Net Request API to block content in a Safari Web Extension. However, not everything in the API has been implemented just yet. The supported RuleCondition are domainType, excludedResourceTypes, isUrlFilterCaseSensitive, regexFilter, and resourceTypes. Does anyone know when the initiatorDomains rule condition will be supported? In the meantime, is there a way for an extension to block requests based on an originator domain? Thanks
Posted
by
Post not yet marked as solved
3 Replies
1.3k Views
I'm not sure what is special about Gmail, but my declarativeNetRequest rules are totally ignored. I make an web extension that blocks email trackers (1x1 pixel images embedded in emails to track if and when you open email sent to you). All images in Gmail are loaded through Google's proxy: googleusercontent.com/proxy/#originalURL But no matter what I do, I can't block a single image that is loaded in an email. To try and prove it is a bug in Safari, I created a new template web extension in Xcode. I block all resourceTypes (images and other should be all that is needed) and added two rules: Block all images loaded through Google's proxy server (this should block all embedded images in all emails) Block any image with copper in the URL (just in case the blocking doesn't apply to the proxy root url for some reason).  {   "id": 1,   "priority": 1,   "action": { "type": "block" },   "isUrlFilterCaseSensitive": false,   "condition": {    "regexFilter": "googleusercontent.com/proxy",    "resourceTypes": [     "image",     "media",     "main_frame",     "sub_frame",     "stylesheet",     "script",     "font",     "xmlhttprequest",     "ping",     "websocket",     "other"    ]   }  },  {   "id": 2,   "priority": 1,   "action": { "type": "block" },   "isUrlFilterCaseSensitive": false,   "condition": {    "regexFilter": "copper",    "resourceTypes": [     "image",     "media",     "main_frame",     "sub_frame",     "stylesheet",     "script",     "font",     "xmlhttprequest",     "ping",     "websocket",     "other"    ]   }  } ] Even though I know this isn't needed, I also added the requester domain (mail.google.com) and the proxy domain (googleusercontent.com) to the permissions list in the manifest file: ... "declarative_net_request": {    "rule_resources": [{      "id": "ruleset_1",      "enabled": true,      "path": "rules.json"     }]   },  "permissions": [    "declarativeNetRequest",    "*://mail.google.com/*",   "*://*.googleusercontent.com/proxy/*" ] If I open an email from copper, the image still loads in Gmail If I right click and select "Open Image in New Tab", the image will not load and I am told it was blocked If I open a test page that has two images in it, one the image from the email, the image is blocked and the other image is not (as expected, the second image is from wikipedia and should not be blocked) Running the same extension in Chrome DOES block the image in Gmail (and in all the other cases too)
Posted
by
Post not yet marked as solved
4 Replies
2.2k Views
So I've been trying to debug / read console.logs from background scripts when using manifest v3 but it never fires any log. It works well in manifest v2 though. I have set the persmission and host_permission as well changed my background to service_work in manifest but nothing really happens: "background": { "service_worker": "scripts/background.js" }, My Qyestion is, is it currently possible to use manifest v3 on iOS safari web extension? Some Notes: Reading this page: https://developer.apple.com/documentation/safariservices/safari_web_extensions/assessing_your_safari_web_extension_s_browser_compatibility It says: "background: In iOS, you must set the persistent attribute to false. With manifest version 3, all background pages are nonpersistent." So I'm guessing it is somehow possible to use right?
Posted
by
Post not yet marked as solved
1 Replies
1.9k Views
I'm getting the following error when I try to import my service worker script: [Error] Failed to load resource: unsupported URL (background_ah.worker.js, line 0) [Error] NetworkError: Load failed Using the following code: try { self.importScripts('./background_ah.worker.js'); } catch (e) { console.error(e); } Am I doing something wrong? The file is there but from the error it seems the extension protocol is not supported at all. It works in Chrome and it's based on this: https://stackoverflow.com/questions/66406672/chrome-extension-mv3-modularize-service-worker-js-file
Posted
by
Post not yet marked as solved
2 Replies
1.7k Views
I have a chrome extension that was converted to Safari extension using xcode safari-web-extension-converter utility. With that, everything except one thing seems to be fine. In the background script, I am loading some data from a web accessible resource like so: export const fetchConfig = async () => { let dataURL = ''; if (!checkBrowser(BROWSERS.Chrome, true)) { dataURL = chrome.runtime.getURL('config.json'); } else { dataURL = browser.runtime.getURL('config.json'); } const res = await fetch(dataURL); return await res.json(); } This works for all browsers except Safari. Where I am getting the runtime URL as: safari-web-extension://E522689D-94A6-4561-90F3-BF22C7848965/config.json but the fetch call fails with the error: Failed to load resource: unsupported URL I have not been able to find anything on this in the documentation, but can we not access the web accessible resources in background in Safari? My manifest file looks like this: { "manifest_version": 3, "name": "Ext Dev", "author": "Test", "description": "Test", "version": "1.1.0", "icons": { "16": "assets/icon/icon16.png", "32": "assets/icon/icon32.png", "48": "assets/icon/icon48.png", "128": "assets/icon/icon128.png" }, "host_permissions": [ ... host addresses here ... ], "permissions": ["storage", "tabs"], "content_security_policy": { "extension_pages": "script-src 'self'; object-src 'self';" }, "web_accessible_resources": [{ "resources": ["config.json"], "matches": ["<all_urls>"] }], "content_scripts": [ { "matches": ["<all_urls>"], "js": ["content.js"], "css": ["commonstyles.css"], "run_at": "document_end", "all_frames": true } ], "background": { "service_worker": "background.js" }, "action": { "default_title": "Ext Client", "default_icon": { "20": "assets/icon/icon20.png", "40": "assets/icon/icon40.png" } }
Posted
by
Post marked as solved
4 Replies
1.8k Views
I'm using manifest v3 and working on a Safari extension. When I try to run a function within activeTab. I can not get the proper return from the the function. For example: browser.scripting.executeScript({ target:{tabId:tab.id}, func:()=>'test', }).then(result=>{ console.log('result',result) }) Here the result is always null. Is it a bug? Nothing wrong with permission settings because if I use files instead of func, the return value works properly. Safari: Version 16.1 (18614.2.3.1.1) macOS 13.0 Beta Xcode: Version 14.0 beta 5 Thanks
Posted
by
Post not yet marked as solved
1 Replies
1.3k Views
I'm porting a Chrome extension to Safari. All works well besides the auth flow, which uses SameSite=Strict cookies. On Chrome, such cookies are easily set and work as expected, but not on Safari. Now, as I understand, technically, requests from chrome-extension:// and safari-web-extension:// origins are cross-site in relation to the server, which makes me think that on Chrome, the SameSite=Strict attribute is simply ignored as an exception for extensions. With that said, the backend team wants to keep the attribute for security reasons and so removing it or replacing it with SameSite=None isn't an option. Is this an intended behavior of Safari or a bug? Is there a way to get around this without changing the attribute?
Posted
by
Post not yet marked as solved
2 Replies
1.2k Views
I migrated my extension from Manifest V2 to V3 recently, and it works fine on Chrome/Edge, but got failed on Safari. The only error message that I can see is: 由于出现错误,service_worker脚本载入失败。 It says service_worker failed to load. There is no other messages I can found. Can you please tell me how to get more informations about the error? Thanks!
Posted
by
Post not yet marked as solved
5 Replies
1.1k Views
We have a Safari browser extension experiencing an issue we believe the be caused by an iOS bug. The issue is affecting physical devices, particularly iPads with low amounts of RAM. When RAM usage goes up, iOS appears to kill the Service Worker to free up memory. Then, even after the RAM usage has gone down, the Service Worker does not come back. The only way to bring it back is for the user to manually disable and re-enable the extension, meaning any functionality that required the Service Worker to function remains broken. We have been able to reliably reproduce this crash on multiple mobile devices We do not see any memory leaks or particularly high usage, but we do see low memory warnings. The worker appears to be killed when RAM usage hits approx. 80%. Note that this is NOT related to the normal lifecycle of a service worker, once the background process is killed the connection is completely severed and it can not recover on its own.
Posted
by
Post not yet marked as solved
1 Replies
778 Views
I'm not sure what is special about Gmail of if this is an issue on other sites as well, but my declarativeNetRequest rules are totally ignored in a Safari Extension that runs on Gmail. I make an web extension that blocks email trackers (1x1 pixel images embedded in emails to track if and when you open email sent to you). All images in Gmail are loaded through Google's proxy: googleusercontent.com/proxy/#originalURL But no matter what I do, I can't block a single image that is loaded in an email. To try and prove it is a bug in Safari, I created a new template web extension in Xcode. I block all resourceTypes (images and other should be all that is needed) and added two rules: Block all images loaded through Google's proxy server (this should block all embedded images in all emails) Block any image with copper in the URL (just in case the blocking doesn't apply to the proxy root url for some reason). {   "id": 1,   "priority": 1,   "action": { "type": "block" },   "isUrlFilterCaseSensitive": false,   "condition": {    "regexFilter": "googleusercontent.com/proxy",    "resourceTypes": [     "image",     "media",     "main_frame",     "sub_frame",     "stylesheet",     "script",     "font",     "xmlhttprequest",     "ping",     "websocket",     "other"    ]   }  },  {   "id": 2,   "priority": 1,   "action": { "type": "block" },   "isUrlFilterCaseSensitive": false,   "condition": {    "regexFilter": "copper",    "resourceTypes": [     "image",     "media",     "main_frame",     "sub_frame",     "stylesheet",     "script",     "font",     "xmlhttprequest",     "ping",     "websocket",     "other"    ]   }  } ] = = = = = = Even though I know this isn't needed, I also added the requester domain (mail.google.com) and the proxy domain (googleusercontent.com) to the permissions list in the manifest file: ... "declarative_net_request": {    "rule_resources": [{      "id": "ruleset_1",      "enabled": true,      "path": "rules.json"     }]   },  "permissions": [    "declarativeNetRequest",    "*://mail.google.com/*",   "*://*.googleusercontent.com/proxy/*" ] = = = = = = If I open an email from copper, the image still loads in Gmail: = = = = = = If I right click and select "Open Image in New Tab", the image will not load and I am told it was blocked = = = = = = If I open a test page that has two images in it, one the image from the email, the image is blocked and the other image is not (as expected, the second image is from wikipedia and should not be blocked) = = = = = = Running the same extension in Chrome DOES block the image in Gmail (and in all the other cases too) = = = = = = Sidenotes: This is a reposting of this post which was locked when the wwdc21-10131 tag was applied to the post which disabled my ability to reply, comment, or update the post. Please do NOT apply tags that lock the post. As requested on the original post by @bweinstein, I filed a bug report on Feedback assistant under FB 10544296 last year and haven't gotten any replies on it. I verified before reposting this (on Mar 1, 2023) that the bug still exists.
Posted
by