Explore the integration of web technologies within your app. Discuss building web-based apps, leveraging Safari functionalities, and integrating with web services.

All subtopics
Posts under Safari & Web topic

Post

Replies

Boosts

Views

Activity

App clips - Launch appclip safari in html page inside safari on a button click. I have the testflight app
Subject: Help Needed with App Clip Implementation Hi Team, I need some assistance with implementing App Clip behavior in safari and also experimenting using TestFlight app. Default App Clip URL: https://appclip.apple.com/id?p=com.jey.ppclient-prod.appclip Website for App Clip Integration: https://appclip-sand.vercel.app/customer Current Behavior: Default App Clip URL: When I embed the default App Clip URL in an HTML tag like below: Launch App Clip it does launch the App Clip. but it says the appclip not supported in your region I've already added this configuration under Local Experience in App Store Connect. Website Integration: I’ve registered the site using the Advanced App Clip Experience. The apple-app-site-association file is in place. When I visit the site, the App Clip does launch as expected. What I Need Help With: I want to launch the App Clip from a custom button click, using either: The default App Clip URL, or The website URL (e.g., https://appclip-sand.vercel.app/customer) with additional query parameters like userId or sessionId. Is there a supported way to achieve this—perhaps through JavaScript or a specific tag setup that works with either Local or Advanced Experience? Your guidance would be greatly appreciated. Thanks, Jey
1
0
105
Jun ’25
Calling SFContentBlockerManager.reloadContentBlocker from related App extension intermittently fails
I have an app which has at least two extensions: A Content Blocker extension with a request handler that returns an appropriate NSExtensionItem as part of beginRequest. A different file URL is returned depending upon if the content blocking is on or off by a user setting A Safari Web Extension that includes a toolbar button and popover that enables users to enable or disable the ad blocking of the content blocker extension All three targets (App, Content Blocker appex and Web Extension appex) use an App Group default to read and set the on or off status of the content blocking. When the user changes the content blocking status, the app group default is updated and SFContentBlockerManager.reloadContentBlocker(...) is called. The Content Blocker extension reads the default and then returns the appropriate file URL. The issue is, I have noticed that whenever SFContentBlockerManager.reloadContentBlocker(...) is called from the app, Safari always applies the correct rules from the returned file URL. However sometimes when SFContentBlockerManager.reloadContentBlocker(...) is called from the Safari Web Extension using native messaging, Safari does NOT apply the correct rules from the returned file URL. Using logging I have confirmed that the Content Blocker extension always returns the appropriate file URL irrespective if called as a result of the app or the web extension. Despite this, Safari does not seem to always apply the returned file URL rules when it is called from the Safari Web Extension appex. In these cases, quitting Safari and relaunching it seems to make it apply the rules correctly (obviously this is applying it due to its launch state, not due to the Web extension appex asking it to do so at that point). All targets have access to the App Group location where the active content blocking file URL belongs and the inactive content blocking file URL is within the Safari content blocker target as a resource. I don't think this is a memory status issue as I cannot see the Content Blocker extension being killed when it returns complex rules --- the fact it always works when called via the app also seems to rule this possibility out. This brings up a number of questions: Is calling SFContentBlockerManager.reloadContentBlocker(...) from a different appex, of the same app target and app group supported? (it seems to work sometimes and did work in previous versions of the app). Is there an issue that the Content Blocker extension sometimes returns a file URL that perhaps the calling Web Extension appex may not have access to (even though Safari should via the Content Blocker extension)? Any other ideas of why this may not be working correctly? Has anyone else experienced this? It seems to happen on both iOS and macOS Safari using the same codebase.
1
0
129
Jun ’25
LocalOverride Request regular expression broke dev tools
Hello, I'm using Safari 18.2 on Sonoma 14.6.1. I was using the Developer Tools to do a Local Request Override in the Source tab for a CSS file that had a changing query string. I thought I had a good regular expression to catch all variants, but apparently it was too generic and possibly wrong, and made both Source and Network tabs no longer work in my Safari. The regular expression I entered for the Local Request Override was: //build/style.css(?.*)?$ Now my dev tools is broken to the extent that the Source and Network tabs no longer work. The slide-out panel on Source that shows Breakpoints, LocalOverrides, etc no longer shows. The toggle for it does, but does nothing now. UI in general looks a little wack on both tabs. So, since I can't turn off the Local Request Override, I've been trying to locate where Safari may have stored it to manually delete it. Not having a lot of luck on that front. It seems to me that Safari was unable to escape my regular expression correctly and it then causes additional issue. Just a guess though. Any advice or help in getting Safari Source & Network working again / manual removal of the LocalOverride would be greatly appreciated. I'm fluent in OSX and Linux, but grep was not much help surfacing anything that worked. Thanks in Advance, possibly a Safari bug as well.
2
0
520
Oct ’25
WKNavigationDelegate methods not getting called even though
Hi everyone, We work on a macOS plugin which then gets loaded into another application. I'm trying to load a webpage in that application through our plugin using a WKWebView & I set my class as the navigationDelegate for the same. I do not receive any callbacks for the WKNavigationDelegate methods. I have debugged & made sure that the navigationDelegate is actually set to my class. Here is a sample code of what I'm doing : [[NSApplication sharedApplication] runModalForWindow:self.mWindowController.window]; - (void)windowDidLoad { [super windowDidLoad]; [self.window makeKeyAndOrderFront:self]; [self.window orderFrontRegardless]; if (self.mLoadingView == nil) { self.mLoadingView = [[LoadingView alloc] initWithFrame:[[self.window contentView] frame]]; } [[self.window contentView] addSubview:self.mLoadingView]; [self.mLoadingView showLoadingView]; [self.window setLevel:NSMainMenuWindowLevel]; [self loadWebPage]; } -(void)loadWebPage { [self.mWKWebView setUIDelegate:self]; [self.mWKWebView setNavigationDelegate:self]; [self.mWKWebView stopLoading]; NSURL *lURL = [self samplePageURL]; WKNavigation *lNavigation = [self.mWKWebView loadRequest:[NSURLRequest requestWithURL:lURL]]; } - (void)webView:(WKWebView *)pWKWebView didFinishNavigation:(WKNavigation *)pNavigation { [self removeLoadingview]; [self.mWKWebView evaluateJavaScript:@"document.body.setAttribute('oncontextmenu', 'event.preventDefault();');" completionHandler:nil]; } I do not get any calls in the webView:didFinishNavigation: & I also tried other methods like webView:didStartProvisionalNavigation, webView:didFailProvisionalNavigation:withError: etc but did not receive any call in those either. Instead of runModalForWindow: if I use showWindow: on the mWindowController the webpage somehow loads but I still don't get any callbacks & so the loadingview subview is also present. The WKWebView is placed in a storyboard, and I have an IBOutlet connected to it in my class. Has anyone faced a similar issue or can point me to something I might be missing? All help is appreciated. Thanks in advance.
2
0
110
Jun ’25
MediaRecorder as PWA on iOS
Hey, very strange problem I have on iOS when shared web as an app (pwa) to home screen. Whenever I use it via safari browser on iPhone, it works 100% fine every time. However, when I put it as an app on home screen, first time I open it it works fine, when i close it and reopen again, it just doesnt start recording. I have to restart my phone for it to work. So it works one time, I guess somehow it doesnt end stream or something, but in code I've tried all the possible ways to close and clean the track. tried GPT, Claude, Gemini solutions. nothing worked, it just works 1 time as PWA. my last hope is someone else encountered this issue and may try to help me ? https://pastebin.com/85i2L2vH
1
0
327
Aug ’25
Issue with Declarative Net Request Rule (DNR) Persistence Across Redirects in Safari
When a DNR rule is set for a specific URL and the request receives a server-side redirect (e.g., 302) to a different URL that does not match the urlFilter, the rule still seems to apply to the redirected request. We are using macOS 15.4 and Safari 18.4. For example, consider two sequential calls: call1 and call2. call1 triggers a 302 redirect to call2. A DNR rule is created to add a "Cookie" header to call1 based on its URL. Unexpectedly, the same cookie is also added to call2, even though call2's URL does not match the rule's urlFilter. This results in the Set-Cookie response from call1 being ignored, and call2 receiving the manually set cookie instead—leading to incorrect behavior. This issue doesn't occur in Chrome or Firefox, where the rule is not applied to the redirected request if the URL no longer matches. We are looking for assistance in fixing these issues and having our Safari Extension function the same as it does in Firefox and Chrome.
0
0
159
Apr ’25
How do I add a UI to a Safari Web Extension?
I have a Safari Web Extension that successfully receives a message from a webpage and returns a response. I now want to add a user interface to the Safari Web Extension. How do I do this? I have modified the default template code as follow to add an NSAlert for testing. The modal runs, but no alert ever appears, and the code remains stuck at runModal. What is the correct way to add a UI to a webextension? - (void)beginRequestWithExtensionContext:(NSExtensionContext *)context {     id message = [context.inputItems.firstObject userInfo][SFExtensionMessageKey];     NSLog(@"Received message from browser.runtime.sendNativeMessage: %@", message);     NSAlert* alert = [[NSAlert alloc]init];     [alert setMessageText:message[@"request"]];     [alert setInformativeText:@"Hello"];     [alert runModal];     NSExtensionItem *response = [[NSExtensionItem alloc] init];     response.userInfo = @{ SFExtensionMessageKey: @{ @"id": message[@"id"], @"uuid": message[@"uuid"], @"contentType": message[@"contentType"], @"response": message[@"request"] } };     [context completeRequestReturningItems:@[ response ] completionHandler:nil]; } @end
3
0
1.3k
Mar ’25
Is the branded email feature available in France? What is the timeline?
Hello, I followed the instructions to set up a custom logo for our domain name Allogarage.fr, both for the brand and the domain. Everything appears to be correctly configured in Apple Business backend for several weeks now, but the logo still doesn’t show up in Mail. Is the branded email feature available in France? Are there any additional steps required?
0
0
151
Jun ’25
Disable recording of Screentime for WKWebView with STWebpageController?
Hi, it seems that with iOS26 the system displays two entries in the screentime report for apps that use a WKWebView: one for the app itself and one for the website that was displayed in the app. We don't see this behaviour in iOS18.7. I'm reseaching how to disable the recording for the webviews in one of our apps (written in Swift with UIKit). The STWebpageController looked promising, especially the field suppressUsageRecording, but the whole class is poorly documented. We initialized it with the bundle identifier of the app and set the url of the wkwebview as the url in STWebpageController. It looks a bit like this: webView = WKWebView(frame: .zero, configuration: config) view.addSubview(webView) //setup STWebpageController webpageController = STWebpageController() do { try webpageController!.setBundleIdentifier(bundleIdentifier) } catch{ } webpageController!.suppressUsageRecording = true addChild(webpageController!) view.addSubview(webpageController!.view) webpageController!.view.frame = view.frame webpageController!.didMove(toParent: self) //load url in webView let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData) webview.load(request) webpageController?.url = request.url This has no effect on the recorded screentime for the webview inside our app - we still see the same time for the container app and the included webview. Any suggestions? Thanks, Heiko
0
0
292
Oct ’25
Repeated Camera Permission Prompts in Web App on Safari (iOS)
Hi everyone, We're building a web application using Next.js that captures around 40 images across different routes as part of a guided user flow. At the beginning of the process, we explicitly request camera permission using navigator.mediaDevices.getUserMedia(...), and the user grants it successfully. However, as users proceed through the flow (navigating between routes), Safari on iOS intermittently re-prompts for camera access—despite the initial permission already being granted and the origin (domain) remaining unchanged. This repeated prompting interrupts the user experience significantly. What we’ve tried: Ensuring camera access is requested only once and reused where possible. Using persistent media stream across routes (where feasible). Testing across different iOS versions to confirm consistency. Questions: Is there a known workaround or best practice to persist camera access across route transitions in a SPA/PWA context on iOS? Are there any Safari-specific behaviors or restrictions related to WebRTC / getUserMedia we should be aware of? Would embedding the camera view in an iframe or maintaining a persistent component help avoid re-prompting? Any guidance or shared experience would be greatly appreciated. Thanks in advance!
Topic: Safari & Web SubTopic: General
0
0
78
Jun ’25
Push Notifications Not Working in iOS App or Safari Browser Created via PWA Builder
Push Notification Issue in iOS PWA App We’ve been trying to implement push notifications in our iOS app, which is a wrapper around a Vite PWA built using PWA Builder. Here's a detailed overview of the issues we’re facing: Problem Summary We originally had a working Vite PWA and used Firebase Cloud Messaging (FCM) for push notifications. When converting this PWA to an iOS app using PWA Builder: The notification permission prompt did not behave as expected in Safari. Even after requesting permission via a user gesture (e.g., button press), FCM token was not received. On Safari (both Mac and Windows), permission sometimes works, but the token isn’t saved until Safari is closed and reopened. In the iOS PWA app, the FCM token never gets retrieved. We tried the same process on Chrome, and everything works flawlessly there. What We’ve Tried Wrapped the permission request and FCM token logic in a user gesture (e.g., button click), as recommended. Confirmed our manifest includes all necessary fields (see below). Tested across macOS, Windows, Safari (desktop), and the iOS app. Manifest.json { "name": "Periscopio", "short_name": "Periscopio", "start_url": "/", "display": "standalone", "background_color": "#f2f2f2", "lang": "en", "scope": "/", "description": "Facilitates the collection of primary data for market research purposes.", "icons": [ { "src": "/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png", "purpose": "any" }, { "src": "/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png", "purpose": "any" }, { "src": "/maskable_icon_x192.png", "sizes": "192x192", "type": "image/png", "purpose": "maskable" }, { "src": "/maskable_icon_x512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" } ], "edge_side_panel": { "preferred_width": 400 }, "display_override": [ "window-controls-overlay", "standalone" ], "theme_color": "#08244c", "orientation": "portrait" } Core Logic (Plain TypeScript) 1. Request Notification Permission + FCM Token async function handleRequestPermission(): Promise<string | null> { try { console.log("Requesting notification permission..."); const permission = await Notification.requestPermission(); console.log("Notification permission result:", permission); if (permission === "denied") { console.error("Notification permission was denied."); return null; } const token = await requestFCMToken(); console.log("FCM Token:", token); if (token) { console.log("Notification setup successful."); return token; } else { console.error("Failed to retrieve FCM token."); return null; } } catch (error) { console.error("Error requesting FCM token:", error); return null; } } 2. FCM Token Logic async function requestFCMToken(): Promise<string | undefined> { try { let permission = Notification.permission; if (permission === "default") { console.log("Requesting notification permission..."); permission = await Notification.requestPermission(); } if (permission === "granted") { console.log("Notification permission granted."); const isSupportedBrowser = await isSupported(); if (!isSupportedBrowser) { console.error("This browser does not support FCM."); return; } const registration = await navigator.serviceWorker.register("/firebase-messaging-sw.js"); console.log("Service Worker registered:", registration); const token = await getToken(cloudMessaging, { vapidKey: "YOUR_PUBLIC_VAPID_KEY_HERE", serviceWorkerRegistration: registration, }); if (token) { console.log("FCM Token:", token); localStorage.setItem("fcmToken", token); return token; } else { console.warn("No registration token available. Request permission to generate one."); return; } } else if (permission === "denied") { console.warn("Permission to notify was denied."); return; } else { console.warn("Notification permission not granted."); return; } } catch (error) { console.error("Error getting FCM token:", error); return; } } Request for Help We’d really appreciate support from anyone who’s successfully implemented FCM push notifications in a Vite PWA wrapped as an iOS app using PWA Builder. Is there something we’re missing about how iOS Safari handles push permissions in PWA mode? Could there be an issue with the service worker or the manifest setup that causes the token not to register? Any Safari-specific quirks to be aware of? Thanks in advance!
Topic: Safari & Web SubTopic: General
0
0
139
Apr ’25
[iOS 26 Beta] event.target.value is always empty — only from specific script domains
Hey everyone, After installing iOS 26 beta, I started noticing unexpected behavior in our input event handlers. Specifically, when users type into an field, event.target.value is always an empty string — but only when the JS file is loaded from a specific domain (e.g., t1.daumcdn.net). The exact same code works perfectly when hosted on other domains like t2.daumcdn.net or search1.daumcdn.net. 👉 I created a demo here: 🔗 CodePen Demo The scripts loaded from each domain are 100% identical (apart from the top-level selector). Before iOS 26 beta, this worked fine. I suspect this is related to ITP or some new cross-origin behavior in Safari, but I’d love to know if anyone else is running into this — or if someone knows a workaround. Thanks!
1
0
147
Jun ’25
iOS 18 upgrade: website map point text now missing after
My website ccflood.us is a simple map that uses a CSV file for the data that is displayed on the map. It uses the ESRI JS API. Recently the points on the map began missing the text in the boxes only on Apple devices that have been upgraded to iOS 18. Has anyone also had this happen to their site? If you have upgraded to iOS 18, try this site on your iPhone then look at it on an Android phone or your desktop browser. You should seet the values in the boxes and a "+" at points that have no value. If you've had this happen with your site or have heard of a fix, please reply to this post.
Topic: Safari & Web SubTopic: General
1
0
374
Mar ’25
Suggestions for OAuth2 in Swift
Hello! I have a few questions about integrating an OAuth2 API into my Swift application. I am using this API to access user data from the website (users will authenticate themselves within the app). I have seen other apps use this API in the way that I am describing it so I know that it is possible. However, I am not sure how to implement it. Are there any recommended ways to use an OAuth2 API in my application? The API that I am using does not specifically say that it supports PKCE. However, I have heard from some sources that it does. If it does not support PKCE, how do I still create a secure app infrastructure that will pass App Store Review? At a more basic level, what is the difference between OAuth2 and PKCE? What should I use in my app? Are there any resources to learn a little bit more about these protocols so that I understand them better? Thanks!
0
0
82
Jun ’25
Declarative Web Push
Anybody succeeded sending a Web Push Message using the new Declarative approach introduced with Safari Version 18.4 (20621.1.14.11.3)? I will help as well if someone can point me to a solution debugging the entire system using Xcode and Minibrowser? Currently I can't get the MiniBrowser connected to the WebPush Daemon.
0
0
240
Mar ’25
iOS Safari - Input element is unresponsive when modifying DOM via a touch event (touchstart, touchmove, touchend, etc)
This is a really strange issue on iOS Safari. Under certain conditions a basic input element will not be focusable or show the on screen keyboard. I can reproduce the issue with a very simple HTML file by dynamically adding an anchor element with an href during a touch event. If you add a different element or an anchor without an href, there is no issue. Similarly, if you apply the same listener to a click event there is no issue. Reproducible in iOS Simulator 17.2 and 18.1 This HTML/JS showcases the problem: <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>InputIssue</title> <meta name="viewport" content="width=device-width, initial-scale=1" /> </head> <body> <div id="parent"> <input type="text" name="test" /> <div id="child"></div> </div> <script> document.addEventListener("touchstart", () => { const child = document.getElementById("child"); if (!child) return; while (child.firstChild) { child.removeChild(child.firstChild); } const link = document.createElement("a"); link.href = "https://test.com"; link.textContent = "test"; child.appendChild(link); }); </script> </body> </html>
Topic: Safari & Web SubTopic: General
0
0
188
Oct ’25