Since Safari requires a macOS app as a container for Web Extensions, is there a way to establish native messaging directly from SafariWebExtensionHandler using stdin/stdout? Or does Safari enforce a different communication mechanism?
I’d like to keep the same approach as other browsers.
Any guidance on making this work would be appreciated!
Explore the integration of web technologies within your app. Discuss building web-based apps, leveraging Safari functionalities, and integrating with web services.
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
I'm trying to use ES6 module imports in a Safari Web Extension, but despite enabling "type": "module" in the manifest, imports are not functioning as expected.
Specifically when working with a project structure that includes multiple directories.
A root directory containing the manifest.json and main entry point scripts
A scripts/ folder housing core functionality modules
A common/ directory for shared utilities, constants, and helper functions
A background.js file in the root that attempts to import from these various directories
When trying to import modules from the scripts/ and common/ directories into my background.js, I'm encountering complete import failures.
How can I correctly implement cross-directory module imports in Safari Web Extensions?
After upgrading to Xcode 15.2 or above(Till Xcode 16.2), users are unable to open Site B (HTTP URL) from Site A (HTTP URL) within our Browser app when loaded in WKWebView. Clicking the link to Site B results in a spinning wheel, but the site does not load. This issue is not present when the app is built with Xcode 15.0.1.
Additionally:
Users are connected to a VPN, which is required to access the sites.
Site A and Site B are on different domains (cross-domain request).
Expected Behavior:
Clicking the link to Site B should successfully load the site with user information passed from Site A.
Current Behavior:
Clicking the link results in a spinning wheel, but Site B does not load inside WKWebView.
Technical Details:
Both Site A and Site B use HTTP (not HTTPS).
Site A and Site B have different domains (cross-domain request).
Do not use location.href for transitions. Instead, we temporarily set about:blank in an iframe and then submit data via a form to the target system’s URL within the iframe.
This approach worked in Xcode 15.0.1 but fails in Xcode 15.2 or above.
Users are connected to a VPN, which is required to access the sites.
WKWebview is not receiving navigation delegate callback for Site B
Steps to Reproduce:
Ensure the device is connected to a VPN.
Open the app (using WKWebView) built with Xcode 15.2 or above.
Load Site A (HTTP) within the app in WKWebView.
Click the link to Site B (HTTP), which should open in an iframe.
Observe that a spinning wheel appears, but Site B does not load.
Environment:
Xcode Versions Affected: 15.2 or above (issue present), 15.0.1 (no issue)
iOS Version: All iOS versions
Devices: iPad
Questions:
Has there been any change in WKWebView’s handling of HTTP URLs or VPN-related network traffic in Xcode 15.2?
Are there any new security policies, iframe restrictions, or VPN-related changes in this version that might be affecting this behavior?
Request for Assistance:
Can you confirm if this is a known issue or an intended change?
Are there any workarounds available?
From a mail app or similar, when opening a webpage in Safari as an external browser, JavaScript on the webpage stops running if Safari goes into the background. Is there a way to prevent this from happening?
Sample code for the counter:
Behavior: Upon returning from the background, the counter continues for about 7-8 seconds but does not progress further.
For example, if Safari is kept in the background for about 20 seconds and then brought back, the counter stops at around 7-8 seconds and only resumes counting after returning to the foreground.
Expectation: The counter should continue running even if Safari goes into the background.
Background
On iOS 18.4 beta, setting a content inset on a WKWebView causes touch events inside the web view to be offset by the content inset amount. In other words, if the web view has a top content inset of 75 points, I must tap 75 points above the intended element for the touch to register correctly. This makes any web content unusable when a content inset is present.
A sample app demonstrating the issue is available here: GitHub - iOS18.4-Webview-Bug.
The issue does not occur in iOS 18.3 or 18.2.
Bug Report
The bug has been reported and fixed at WebKit Bug 289715 and also filed as rdar://147075945.
Question
Will the fix be included in the upcoming iOS 18.4 beta release (Beta 5) or soon thereafter?
I am calling fetch with a POST on page1 in Safari. No special cache parameters on the fetch call.
The response from the server is a 303 redirect to page2
The second page -- page2 -- is in my browser's cache with cache-control "public, max-age=31536000, immutable".
For some reason, the page2 redirect is causing a server hit to re-GET the second page every time instead of pulling from cache.
If I instead directly get the second page by doing a fetch on page2, there is no server hit.
If I do this on Chrome or Firefox, it behaves as I would expect, pulling page2 from the cache with no server hit.
In case it matters, the fetch is coming from within an iFrame. Also, if I change the original POST to a GET, the problem still happens.
I am using a pretty old version of Safari on my Mac, so I could chalk it up to that, but I am getting the same behavior with Safari on my iPhone with iOS 18.3.2
Any ideas?
Thanks.
Hey team, I've integrated custom WkWebsiteDatastore to manage profiling for different sessions.
upon testing the WkWebsiteDataStore as its mentioned to be persistent But
The storage can be accessed via identifier, But the session data in storage is absent, such as cookies caches all are cleared when app is relaunched
is it the default behavior to be expected or there is some property missing causing the session data to be removed from storage.
Is this symbol, which Safari uses to the left of the address bar, in the public SF Symbols set? What's it called?
I have a business scenario where I want to guide users to Safari and open a Safari extension. How can I open Safari from my app and navigate to a specific webpage?
Topic:
Safari & Web
SubTopic:
General
The order nor -webkit-order properties of a child element of a flex parent dosen't work in Safari 18.3.
Works correctly in FireFox and Chrome.
Topic:
Safari & Web
SubTopic:
General
Hello!
While working with the new Apple Pay SDK for iOS 18, I encountered a bug. When using the Ukrainian language, in the modal displaying the QR code, I noticed that there is a missing bracket for the year variable. This causes incorrect data to be displayed in the QR code.
This seems to be a localization issue specifically with the Ukrainian language in the new SDK, as the bug does not occur with other languages like English.
Has anyone else experienced this? Any advice or information on this bug would be appreciated.
Thanks!
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.
Hi Team,
I'm using the simple mailto functionality in the demo page and when I tested the same via Safari mailto functionality is not working.
However, the same feature is working as expected via Chrome.
Demo: https://jsfiddle.net/xut0ed4y/
Kindly help.me to resolve this issue.
When I open com. apple. developer. web browser, I am unable to inject JavaScript into the webview through methods such as addUserScript. The console will prompt 'ignoring user script injection for non app bound domain'
I don't know why but all of a sudden when I build the extension it just doesn't load in Safari. The build executes fine but the extension doesn't load. Sometimes, through trying different combinations of clearing the build folder, building, archiving, ... it suddenly loads. And the next time I build again it doesn't load properly. So I can't do any work on it or test anything.
I don't know why all of a sudden I am getting this behavior. It looks like engineers at Apple are constantly trying to overcomplicate a process that is at least ten times simpler in any other browser. This is ridiculous. Is this what our annual fee goes to? And they don't even provide any support for that. Several times I've tried to get some help here just to have to spend hours upon hours to figure it out by myself. I'm so tired of this.
I want to migrate from a Safari App Extension to a Safari Web Extension, but don't know how to get rid of the message, telling users that my extension can access their passwords. Here is a message which I see:
I was thinking that this might be because all Safari Web Extension get this type of access, but I have a Safari Web Extension which does not require such level of access:
Here is the manifest:
{
"manifest_version": 2,
"default_locale": "en",
"name": "__MSG_extension_name__",
"description": "__MSG_extension_description__",
"version": "1.1",
"icons": {
"48": "images/icon-48.png"
},
"background": {
"scripts": [
"background.js"
],
"persistent": true
},
"browser_action": {
"default_popup": "popup.html",
"default_icon": {
"16": "images/toolbar-icon-16.png"
}
},
"permissions": [
"nativeMessaging", "tabs"
]
}
and here is the Info.plist file:
Here is the entire code of the extension:
https://github.com/kopyl/web-extension-simplified
I'm testing web extension to safari on iOS. I've built and added extension application to simulator, but on safari settings shows no extensions.
I'm using Xcode 16.3 beta 2 with Simulator iOS 18.4 (22E5216h), tested on iPhone 16.
https://app.screencast.com/oUq4EMonmfT7u
https://app.screencast.com/MCquvHzmZi8QS
I'm experiencing issues with audio playback in my React video player component specifically on iOS mobile devices (iPhone/iPad). Even after implementing several recommended solutions, including Apple's own guidelines, the audio still isn't working properly on iOS Safari. It works completely fine on Android. On iOS, I ensured the video doesn't autoplay (it requires user interaction). Here are all the details:
Environment
iOS Safari (latest version)
React 18
TypeScript
Video files: MP4 with AAC audio codec
Current Implementation
const VideoPlayer: React.FC<VideoPlayerProps> = ({
src,
autoplay = true,
}) => {
const videoRef = useRef<HTMLVideoElement>(null);
const isIOSDevice = isIOS(); // Custom iOS detection
const [touchStartY, setTouchStartY] = useState<number | null>(null);
const [touchStartTime, setTouchStartTime] = useState<number | null>(null);
// Handle touch start event for gesture detection
const handleTouchStart = (e: React.TouchEvent) => {
setTouchStartY(e.touches[0].clientY);
setTouchStartTime(Date.now());
};
// Handle touch end event with gesture validation
const handleTouchEnd = (e: React.TouchEvent) => {
if (touchStartY === null || touchStartTime === null) return;
const touchEndY = e.changedTouches[0].clientY;
const touchEndTime = Date.now();
// Validate if it's a legitimate tap (not a scroll)
const verticalDistance = Math.abs(touchEndY - touchStartY);
const touchDuration = touchEndTime - touchStartTime;
// Only trigger for quick taps (< 200ms) with minimal vertical movement
if (touchDuration < 200 && verticalDistance < 10) {
handleVideoInteraction(e);
}
setTouchStartY(null);
setTouchStartTime(null);
};
// Simplified video interaction handler following Apple's guidelines
const handleVideoInteraction = (e: React.MouseEvent | React.TouchEvent) => {
console.log('Video interaction detected:', {
type: e.type,
timestamp: new Date().toISOString()
});
// Ensure keyboard is dismissed (iOS requirement)
if (document.activeElement instanceof HTMLElement) {
document.activeElement.blur();
}
e.stopPropagation();
const video = videoRef.current;
if (!video || !video.paused) return;
// Attempt playback in response to user gesture
video.play().catch(err => console.error('Error playing video:', err));
};
// Effect to handle video source and initial state
useEffect(() => {
console.log('VideoPlayer props:', { src, loadingState });
setError(null);
setLoadingState('initial');
setShowPlayButton(false); // Never show custom play button on iOS
if (videoRef.current) {
// Set crossOrigin attribute for CORS
videoRef.current.crossOrigin = "anonymous";
if (autoplay && !hasPlayed && !isIOSDevice) {
// Only autoplay on non-iOS devices
dismissKeyboard();
setHasPlayed(true);
}
}
}, [src, autoplay, hasPlayed, isIOSDevice]);
return (
<Paper
shadow="sm"
radius="md"
withBorder
onClick={handleVideoInteraction}
onTouchStart={handleTouchStart}
onTouchEnd={handleTouchEnd}
>
<video
ref={videoRef}
autoPlay={!isIOSDevice && autoplay}
playsInline
controls
crossOrigin="anonymous"
preload="auto"
onLoadedData={handleLoadedData}
onLoadedMetadata={handleMetadataLoaded}
onEnded={handleVideoEnd}
onError={handleError}
onPlay={dismissKeyboard}
onClick={handleVideoInteraction}
onTouchStart={handleTouchStart}
onTouchEnd={handleTouchEnd}
{...(!isFirefoxBrowser && {
"x-webkit-airplay": "allow",
"x-webkit-playsinline": true,
"webkit-playsinline": true
})}
>
<source src={videoSrc} type="video/mp4" />
</video>
</Paper>
);
};
Apple's Guidelines Implementation
Removed custom play controls on iOS
Using native video controls for user interaction
Ensuring audio playback is triggered by user gesture
Following Apple's audio session guidelines
Properly handling the canplaythrough event
Current Behavior
Video plays but without sound on iOS mobile
Mute/unmute button in native video controls doesn't work
Audio works fine on desktop browsers and Android devices
Videos are confirmed to have AAC audio codec
No console errors related to audio playback
User interaction doesn't trigger audio as expected
Questions
Are there any additional iOS-specific requirements I'm missing?
Could this be related to iOS audio session handling?
Are there known issues with React's handling of video elements on iOS?
Should I be implementing additional audio context initialization?
Any insights or suggestions would be greatly appreciated!
I have a simple Safari extension which contains only Javascript and no native code.
Currently I have the placeholder SafariWebExtensionHandler.swift that Xcode created when I added the extension. It's not doing anything useful, but simply deleting it doesn't seem to work.
Can I have an extension that includes no native code?
It seems fetch() does not include credentials (cookie) even when credentials: include is used and Safari extension has host_permissions for that domain when using from a non-default Safari profile.
It includes credentials (cookie) when using from the default profile (which has the default name Personal).
Is there anyone who has this problem?
I try to request in popup.js like this:
const response = await fetch(
url,
{
method: 'GET',
mode: 'cors',
credentials: 'include',
referrerPolicy: 'no-referrer',
}
);
and it does not include the credentials (cookie) from host_permissions.
I already posted https://developer.apple.com/forums/thread/764279, and opened feedback assistant (FB15307169).
But it is still not fixed yet. (macOS 15.4 beta 3)
I hope this is fixed soon.