Black screen in Safari after returning from Needle Go AR session

The issue

When I open an AR session via Needle Go from a Safari-hosted Needle Engine page, pressing “Back” or “Quit AR” in Needle Go’s context menu always results in a completely black screen in Safari. The original page is visible in the iOS app switcher (the tab is still open and appears correct), but Safari displays a black page once it comes back to the foreground.

The AR session itself works perfectly, the issue only occurs on return from Needle Go to Safari.


Reproduction steps

  1. Open the Needle Engine project in Safari on iOS (iPhone, Needle Go 1.7 installed)

  2. Tap the AR button on the page

  3. Needle Go opens, AR session starts and works correctly (3D model overlaid on real environment)

  4. Open Needle Go’s context menu (long press), shows “Back”, “Quit AR”, “Reload Page”, “Send Feedback”, “Needle Go 1.7”
    → Before tap on “Back” OR “Quit AR”, Safari still have the pages loaded perfectly in background

  5. Tap “Back” OR “Quit AR”

  6. → Safari comes back to the foreground and displays a black screen

The original Safari tab is visible in the iOS multitasker with the correct page content before step 5.


Technical investigation

Fix attempt 1 — pageshow + bfcache reload

Hypothesis: When navigateNeedleAppClip() runs window.location.href = appclipUrl, Safari navigates away from the page. iOS intercepts and opens Needle Go. The original page is stored in the bfcache. When Needle Go closes, Safari returns but pageshow.persisted = true fires without a handler → WebGL context is suspended → black canvas.

Fix: Added pageshow listener in index.html to force location.reload() when persisted = true.

Result: âś— No change. Black screen persists.


Fix attempt 2 — window.open(_blank) in navigateNeedleAppClip()

Hypothesis: Using location.href navigates Safari’s current tab to the appclip URL. After Needle Go, Safari is left on the blank appclip URL page. Using window.open(_blank) should preserve the current tab.

Fix: Changed navigateNeedleAppClip() to use window.open(urlStr, "_blank", "noopener,noreferrer") with location.href fallback.

Result: ✗ No change. Black screen persists, sometimes with a “◄ Needle Go” indicator visible in Safari’s status bar (meaning Needle Go opened Safari, not the other way around).


Fix attempt 3 — Needle Go Full App user-agent detection

Discovery: DeviceUtilities.isNeedleAppClip() in Needle Engine checks for /NeedleAppClip\//i in the user-agent. Needle Go Full App appears to use NeedleGo/x.x in its user-agent (not NeedleAppClip/), so isNeedleAppClip() returns false even when running inside Needle Go.

This means our patched NeedleXRSession.start was calling navigateNeedleAppClip() even when already running inside Needle Go’s WKWebView — causing Needle Go to open Safari with the appclip URL.

Fix: Added isInAnyNeedleGoContext() helper that checks for both NeedleAppClip/ and NeedleGo/ in the user-agent:

function isInAnyNeedleGoContext(DeviceUtilities: { isNeedleAppClip(): boolean }): boolean {

if (DeviceUtilities.isNeedleAppClip()) return true;

if (typeof navigator === “undefined”) return false;

return /NeedleGo\//i.test(navigator.userAgent);

}

And replaced !DeviceUtilities.isNeedleAppClip() with !isInAnyNeedleGoContext() in the condition.

Result: âś“ AR session now starts correctly in Needle Go Full App. âś— Black screen on return still persists.


Fix attempt 4 — Revert to location.href + visibilitychange resize

Hypothesis: window.open(_blank) creates a new empty Safari tab. When Needle Go closes, iOS focuses this new empty tab (appclip URL → black) rather than the original tab.

Fixes:

  1. Reverted navigateNeedleAppClip() back to location.href (same tab, no new tab created)

  2. Improved pageshow.persisted handler to show the loading screen before location.reload()

  3. Added visibilitychange → resize to let Needle Engine recalculate renderer dimensions after resume

Result: ✗ Black screen still persists after pressing “Back” or “Quit AR”.


Current state / open questions

After extensive investigation, it appears that:

  • The Needle Engine DeviceUtilities.isNeedleAppClip() check fails for Needle Go Full App (only detects the App Clip variant, not the full app). This is the root cause of navigateNeedleAppClip() being called from inside Needle Go, but we worked around it in our own code.

  • Even with the correct AR session starting in Needle Go, pressing “Back” or “Quit AR” consistently results in a black Safari page.

  • The original Safari tab is intact and visible in the multitasker with the correct content — but it displays black when active.

Questions for the Needle team:

  1. What is the exact user-agent string set by Needle Go Full App (not App Clip)? DeviceUtilities.isNeedleAppClip() should ideally detect both variants.

  2. When pressing “Quit AR” in Needle Go’s context menu, does Needle Go close the App Clip / WKWebView entirely, or does it just end the XR session and stay in the WKWebView?

  3. When Needle Go is launched from Safari via location.href = "https://appclip.apple.com/id?p=tools.needle.launch-app.Clip&url=..." — does iOS navigate Safari’s tab to the appclip URL, or does iOS intercept the navigation and leave Safari on the original page? This determines whether the black screen is Safari showing the appclip URL (no content) or Safari restoring our page from bfcache with a broken WebGL context.

  4. Is there a recommended pattern in Needle Engine projects for graceful recovery when Safari returns from background after a Needle Go AR session?

This sounds like the WebGL context might be suspended when returning from Needle Go, leading to a black screen in Safari. It’s tough to diagnose this remotely without seeing the behavior directly.

Can you please provide a URL to your deployed website, or if possible, the output of a bug report from Unity (menu “Needle Engine/Report a Bug”)? That would help us investigate further.

Sources: Needle Engine Docs (64%), Needle Engine Docs (64%)

1 replies left - Become PRO for more replies.
Reply to this post directly if you need further help (bottom right button)

Hi,

  1. Do you have a link to your website?
  2. Does this reproduce for you on any example on https://appclip.needle.tools ?
  3. Which exact device and iOS version are you using?
  4. Is your website running on localhost and uncompressed with many textures or is it a deployed website? Have you tried enabling AutoCompress for previewing compression in localhost/dev?

Basically what the AI asked for :wink:

I’ve been testing this exact flow yesterday for hours on an iPhone in both Safari and Chrome. Needle Go is another App (an AppClip) which opens when you click Enter AR - Safari or Chrome stay open in the Background like any other app.

Hey @Marcel_Wiessler1 :slight_smile:

  1. The website is Rayon X • Échangeur Thermique
  2. yes, it does the same thing on all your samples on https://appclip.needle.tools
  3. I’m on a iPhone 17 Pro on iOS 26.4
  4. the website is deployed on Production in Github Pages with copression

Yes, exactly. That’s why I was wondering why it doesn’t just open back safari how it is.
Most of the people around me use the “Back” button and they get the black window also (in iPhone 13 with iOS 26.x)

Hi, interesting. I’ve tried on an iPhone 11 with iOS 26.3 right now.

The website you linked opened Quicklook and not WebXR / Needle Go - how can i start AR on your website? Quicklook opening and closing worked fine.

Edit: Tried the Enter AR button (Needle Go) now as well and it also seems to work on iOS 26.3 - still testing.

Edit 2: Changed the default brower to Safari on the iPhone and have the same black tab now - it seems like Safari opens a new empty tab when clicking the Back button (instead of focusing the previously active tab, that’s what Chrome does). We will look into this! Thanks for reporting!

Hello @Corentin_Duboc Thanks again for reporting. It will be fixed in the next AppClip update (version 1.8 should be available within 1-2 days)

Hello @Corentin_Duboc

The reported issue should be fixed in 1.8 (it’s already available) and the back button should return to your previous page. Please let me know when you’ve tried.

Another update is on the way right now which fixes a regression related to loading the same experience a second time while the AppClip was still open - should be available soon too!

1 Like

Hello @Marcel_Wiessler1 ,

indeed, it works perfectly now.

Thanks a lot for your speed of action !

:smiling_face_with_sunglasses::fire: