External links and URL handling in your ChatGPT & Codex app
On the web, a link to Stripe, Google login, WhatsApp or your help center just works. Inside an app every link needs a destination: the app itself, an in-app browser tab, Safari or Chrome, or another app such as Mail, Phone or WhatsApp. Get it wrong and users end up stranded on a third-party page with no back button, logged in in the wrong place, or paying in a browser while the app waits.
The success URL returns to your domain with the session intact
Keep external links in the app (option 0), or list these hosts as never-browser exceptions (safariblacklist, BROWSER_BLACKLIST)
Google and Facebook login
Social Login Helper
Google blocks embedded WebViews; the helper runs that step in an accepted login window and returns
google_login_helper_triggers / GOOGLE_LOGIN_HELPER_TRIGGERS; Android also offers the googlelogin:// prefix for a Chrome Custom Tab
Terms, help center, docs, blog on other domains
In-app tab
Address bar and close button; the app stays underneath
alwaysOpenInInAppTab / ALWAYS_OPEN_IN_INAPP_TAB, or target="_blank" with the special-link option set to 1
WhatsApp (wa.me), Instagram, YouTube, X, TikTok
Their app or the system browser
Users are logged in there, not in your WebView
safariwhitelist / BROWSER_WHITELIST
mailto:, tel:, sms:
Mail, Phone, Messages
System schemes, handled by the phone
Use standard links; WebViewGold hands them to the system
App Store and Google Play links
The store app
Updates, ratings, your other apps
apps.apple.com and play.google.com on the always-external list
Prompt for ChatGPT & Codex
Paste this into ChatGPT & Codex to implement the web-app side. Review the result, publish, then test inside the WebViewGold app.
Prompt for ChatGPT or Codex
This web app runs inside the WebViewGold native wrapper (its user agent contains "WebViewGold"). Open a pull request that:
1. renders every link inside AI answers (markdown, citations, sources) with target="_blank" rel="noopener noreferrer" so the app can show it in its in-app browser tab;
2. never turns links to our own domain into new tabs;
3. starts checkout and login with same-window navigation (window.location.href or server redirects) instead of window.open;
4. renders contact actions as mailto:, tel: and https://wa.me/ links;
5. hides digital-subscription checkout links when the user agent contains "WebViewGold";
6. adds a list of all external hosts to docs/links.md and the link policy to AGENTS.md.
Great work! Never coded anything but managed to work with this. Easy and fast! Also with great help from the creators!
Three link classes and the switches that control them
Internal links
Same domain as your configured host. They load in the main WebView, which is why the start URL should be your production domain. Test the subdomains you use for auth, checkout or the API explicitly; whether they count as internal depends on the host you configured.
External links
Every other domain. Option 0 keeps them in the app. iOS can send them to Safari with externalLinkHandlingOptions = 2; Android adds 1 (in-app tab) and 2 (system browser) for EXTERNAL_LINK_HANDLING_OPTIONS. Per-host lists override the default: safariwhitelist, safariblacklist and alwaysOpenInInAppTab on iOS, BROWSER_WHITELIST, BROWSER_BLACKLIST and ALWAYS_OPEN_IN_INAPP_TAB on Android.
Special links
Links with target="_blank" (on Android also links ending in #). specialLinkHandlingOptions and SPECIAL_LINK_HANDLING_OPTIONS: 0 main WebView, 1 in-app tab, 2 browser. On Android a newtab: prefix forces a single link into that behavior. For links that are special and external, Android follows the special-link setting, while on iOS externalLinkHandlingOptions = 2 still sends them to Safari, so keep it at 0 if you want the in-app tab.
Set up link handling for a ChatGPT & Codex app
About 15 minutes with a link inventory, then a test on real phones.
List every outbound link in your ChatGPT & Codex app
Click through or search the code: checkout and billing portal, login providers, social profiles, support chat, legal pages, store badges, mailto: and tel: links, maps. Note the destination for each using the table above.
Set the default
For most apps: keep external links in the app (option 0 on both platforms) and route the exceptions. Sending all external links to the browser breaks payment and login redirects that must come back to the app.
Add the exceptions
Social apps, WhatsApp and store links to safariwhitelist (iOS) and BROWSER_WHITELIST (Android); terms, docs and the help center to alwaysOpenInInAppTab and ALWAYS_OPEN_IN_INAPP_TAB; payment and auth hosts to the never-browser lists if your default is the browser. Enter hosts exactly as you link to them, without https://.
Turn on the login helper
Add https://accounts.google.com to google_login_helper_triggers (iOS) and GOOGLE_LOGIN_HELPER_TRIGGERS (Android). Do not simply send Google to Safari: the session would end up in Safari, not in the app (the disallowed_useragent fix).
Treat digital purchases separately
Stripe for physical goods and real-world services can stay in the app. For subscriptions or credits used inside the app, Apple expects In-App Purchase (Guideline 3.1.1) and Google expects Play Billing, outside the regional exceptions, so hide that checkout inside the app (Stripe vs In-App Purchase).
Test every link type
Load https://www.webviewgold.com/demo/testlinks.php as a temporary start URL to see how each kind of link behaves, then tap every outbound link of your real app on an iPhone and an Android phone, including a full test payment.
A typical starting configuration
Values only: keep the syntax that the lines in your Config.swift and Config.java already use. On Android, ALWAYS_OPEN_IN_INAPP_TAB takes URL prefixes; the other lists take hosts.
Checkout in the browser. Stripe opens in Safari or Chrome, the payment succeeds, the success page loads in the browser and the app still shows the unpaid state. Keep checkout in the app, or bring the return URL back with Universal Links (see the deep-link guide).
Checkout in a pop-up. Code that opens checkout with window.open or target="_blank" becomes a special link, so the success page loads in the in-app tab instead of the app. Navigate with window.location.href instead.
A billing portal link for digital plans in the iOS app. Outside the regional exceptions, Apple can read it as steering away from In-App Purchase (Guideline 3.1.1). Show it on the web only.
A third-party page with no way back. iPhones have no back button. Anything that is not your app belongs in the in-app tab or another app.
WhatsApp, Instagram or map links loading their website inside the app, often behind a login wall. Send those hosts to the system so the real app opens.
Everything opens in Safari. An app that keeps leaving itself feels like a bookmark, which is the impression behind many Guideline 4.2 rejections.
Frequently asked questions
Why does my Stripe checkout lose the session in the app?
Usually because checkout opened in Safari or Chrome: the payment works, but the success URL loads in the browser, where the user is not logged in. Keep checkout.stripe.com in the main WebView (option 0 for external links) and navigate with window.location.href, so the redirect lands back in the app.
Do mailto:, tel: and WhatsApp links work inside the app?
mailto:, tel: and sms: links are handed to Mail, the phone app and Messages. For WhatsApp, add wa.me and api.whatsapp.com to the always-external list (safariwhitelist, BROWSER_WHITELIST) so the WhatsApp app opens instead of the WhatsApp website inside your app. Test each on a real phone.
What is the in-app tab?
A browser view that opens over your app with an address bar and navigation buttons. Users read the page and close it to return exactly where they were. It is the right place for terms, help articles and other third-party content.
Can I open all external links in Safari or Chrome?
You can (externalLinkHandlingOptions = 2 on iOS, EXTERNAL_LINK_HANDLING_OPTIONS = 2 on Android), but then add every payment, login and API host to the never-browser exceptions (safariblacklist, BROWSER_BLACKLIST), or redirects meant for your app will land in the browser.
Can the iOS app link to my web pricing page?
For digital goods, Apple generally does not allow buttons or links to external purchases. Exceptions exist for specific regions, such as the US storefront after the 2025 court order and the EU alternative terms, and they change. Check the current text of Guideline 3.1.1 in App Store Connect before relying on one.
Three ways to get your app into the stores
Same result, different amount of work on your side. All three come with the approval guarantee and 24/7 human support.
Do it yourself
$109 per platform, one-time
The WebViewGold license: a finished Xcode or Android Studio project. Paste your URL, set name and icon, switch on features, build and submit. Free updates forever.
No Mac, no Xcode, no Android Studio: configure in the browser, we build both apps in the cloud and hand them to App Store Connect and the Play Console.
Send us your URL and icon. Our team configures, builds and delivers your app within 72 hours, white-label, with source projects. Both platforms for $1,158.