Android link router: open login links in one browser and everything else in another.
34 KB · no permissions · no internet · open source
Android sends every link to one default browser. Wyelink lets you use two: one for sign-ins (Google, Microsoft, Apple, GitHub, Okta and other login pages, OAuth/SSO flows, "verify your email", magic links, password resets) and one for everything else.
Set Wyelink as your default browser and pick your two browsers. When you tap a link, Wyelink decides in a few milliseconds and hands it over. It never shows a screen of its own.
A wye is a Y-shaped railway junction where one track splits into two. Same idea: one link in, the right browser out.
- Keep all your logins in one browser (say Firefox or Brave with your password manager and sessions) and browse in another (say Chrome).
- Stop "Sign in with Google" in some app from opening in a browser where you aren't signed in.
- Send work links (
app:com.slack,mycompany.com) to a work browser and the rest to a personal one.
- Smart sign-in detection. Scores every link: identity providers,
login.*/sso.*hosts,/login,/oauth2/authorize,/saml,/verify-email,/magic-linkpaths,redirect_uri,code_challenge,oobCode,*_tokenparameters. Vendor marketing pages (okta.com,auth0.com/blog) and docs about authentication stay in Browser 2. - Sees through redirect wrappers, offline. Outlook Safe Links, Proofpoint URL Defense, Google
/url?q=, Facebook, Instagram, Threads, Messenger, LinkedIn, YouTube, Slack, Steam and VK redirects, Amazon SES and Postmark click tracking. - Works with in-app sign-in tabs. Wyelink offers a pass-through Custom Tabs service, so apps that use AppAuth-style sign-in libraries pick it, and their login tab opens in Browser 1. Android's new Auth Tab gets its result passed straight back to the app.
- Your own rules beat detection: domains, paths, the app a link came from, text, regular expressions.
- Try a link: paste any URL to see which browser it goes to and why.
- Share-sheet fallback: share a page to "Open in Browser 1" or "Open in Browser 2" when you want it in the other one.
- Private by design: no permissions, no internet, no logging, no backups. History is off by default and leaves out query strings.
- Tiny and native: pure Java on Android framework APIs, zero libraries, ~34 KB APK. Adaptive and themed (Material You) icon. Light and dark mode.
- Download
Wyelink-1.1.1.apkfrom Releases and open it on your phone (allow "install unknown apps" when asked). - Open Wyelink and tap Make default.
- Pick Browser 1 (sign-ins) and Browser 2 (everything else).
- Optional: add rules, then paste a link into Try a link to check where it goes.
Needs Android 8.0 (API 26) or newer. The SHA-256 checksum is listed with each release.
Releases from 1.1.1 on are signed with Wyelink's own key. If you installed 1.1.0, uninstall it first, because Android won't update an app across a key change. To check an APK yourself, run apksigner verify --print-certs and compare the certificate's SHA-256 digest:
989ede8b395b6d0b89bcd97fffa6244b0a6dd5638c270527fbeb95d385585702
Smart detection reads the link's address, not who sent it, so a fake login page at fake-bank.example/login looks like a sign-in and goes to Browser 1. If Browser 1 is where your accounts are logged in, turn detection off and list the sites you trust:
- Turn off Detect sign-in & confirmation links.
- Add your sites to Always Browser 1, for example
github.com.
Now only those sites reach Browser 1, and every unknown link opens in Browser 2. The trade-off is that a sign-in link from a site that isn't on your list goes to Browser 2 too. Share it to "Open in Browser 1" when you trust it. Wyelink is not a phishing filter, so still check a page before you type a password.
The first match wins:
- Always Browser 1 rules
- Always Browser 2 rules
- An app's Auth Tab sign-in → Browser 1
- (optional) any in-app browser tab (Custom Tab) → Browser 1
- Sign-in score of 3 or more → Browser 1
- Everything else → Browser 2
Wrapped links are unwrapped before steps 1–5, so your rules and the score apply to the real destination. The link you tapped is still the one that opens.
What adds up to a sign-in?
| Signal | Examples | Points |
|---|---|---|
| Sign-in host | accounts.google.com, login.microsoftonline.com, appleid.apple.com, login.live.com, login.yahoo.com |
certain |
| Identity-platform tenant | *.okta.com, *.auth0.com, Cognito, Azure B2C, OneLogin, Duo, PingOne, Kinde, Frontegg, Zitadel, Logto, Ory, Stytch, WorkOS |
certain |
| Known sign-in page | microsoft.com/devicelogin, google.com/device, amazon.com/ap/…, Slack and Notion magic links |
certain |
| Host label | login.*, sso.*, auth.*, idp.* · accounts.* · account.*, id.* |
3 · 2 · 1 |
| Path | /login, /signin, /authorize, /oauth2, /saml, /verify, /confirm, /magic-link, /2fa, verify-email, email_verification · /reset · /auth, /callback, /password |
3 · 2 · 1 |
| Query | redirect_uri, response_type, code_challenge, SAMLRequest, oobCode, confirmation_token · client_id, token, otp, any *_token · scope, state, code, next |
3 · 2 · 1 |
Path points are capped at 3 per link. The full lists are in Router.java.
One rule per line:
example.com domain and all subdomains
example.com/login domain + path prefix
app:com.slack links opened from that app
has:invoice URL contains the text
re:^https://.*\.gov/ regular expression
# comment
- No permissions at all, including no
INTERNET, so the app can't send anything anywhere. - No logging, analytics, crash reporting or third-party code.
- Backups are off: no Google cloud backup and no phone-to-phone transfer.
- Recent links is off by default. When on, it keeps the last 15 links as
scheme://host/pathonly. The part after?is never stored, and long token-like path parts are hidden. - Links are forwarded as a fresh intent. The caller's component, selector, ClipData and URI-permission grants are dropped.
app:rules rely on the referrer Android reports, which the sending app can set itself. Don't treat them as a security boundary.
See SECURITY.md to report a problem privately.
These come from Android and other apps, not from Wyelink:
- Verified App Links (for example, YouTube links when the YouTube app is installed) open the app directly. Android never asks the default browser about them.
- Microsoft's sign-in library (MSAL) only uses browsers on its built-in safe list, and a few apps always open Chrome. Those links never reach Wyelink.
- Native sign-ins (Google one-tap, passkeys, Credential Manager) don't use a browser at all.
- Trackers that hide the destination entirely (SendGrid, Mailgun, HubSpot, bit.ly) can only be read by going online. Wyelink stays offline, so they're routed by their visible URL.
- Keyword detection can't tell a real login page from a fake one, so see Safest setup. A bare
/verifypath such asexample.com/verify/blogstill counts as a sign-in. Use a rule or the share sheet for the rare miss, and report it.
How do I open certain links in a specific browser on Android? Install Wyelink, make it the default browser, choose Browser 1 and Browser 2, and add the sites to Always Browser 1 or Always Browser 2.
Can I use Firefox for logins and Chrome for everything else? Yes. Set Browser 1 to Firefox and Browser 2 to Chrome. Any pair of installed browsers works, for example Brave, Edge, Samsung Internet, DuckDuckGo, Vivaldi or Chrome.
Does Wyelink slow links down? No. It decides in a few milliseconds, with no network request. In-app sign-in tabs skip the browser's prefetching, so the first page can load slightly slower than a direct tab.
Does it work with "Sign in with Google" inside apps? When the app opens its sign-in page in a browser or an in-app tab, yes. Apps that sign in natively (Google one-tap, Credential Manager) don't open a browser at all.
Is it on Google Play or F-Droid? Not yet. Download the APK from Releases.
git clone https://github.com/biteasier/wyelink.git
cd wyelink
./gradlew testDebugUnitTest assembleReleaseThe APK is written to app/build/outputs/apk/release/app-release.apk. Needs JDK 17 and the Android SDK (platform 35). Without the private release key, builds are signed with your local debug key so you can sideload them right away. Those builds can't update an official install. To sign with your own key, point WYELINK_SIGNING_PROPERTIES at a properties file with storeFile, storePassword, keyAlias and keyPassword.
app/src/main/java/app/wyelink/
Router.java rules, sign-in scoring, offline unwrapping (pure Java)
RouterActivity.java invisible "browser" that forwards each link
ShareToBrowser1/2Activity.java share-sheet "Open in Browser 1/2"
CustomTabsPassThroughService.java lets AppAuth-style sign-ins choose Wyelink
MainActivity.java settings screen
Prefs.java settings storage
app/src/main/aidl/…/ICustomTabsService.aidl Custom Tabs contract (AndroidX, Apache 2.0)
app/src/test/java/app/wyelink/
RouterTest.java behaviour tests
CorpusTest.java 137 real-world sign-in links + 71 ordinary links
art/ icon source (SVG) and PNG exports
Found a link that went to the wrong browser? Open a "wrong browser" issue with the tokens removed. Pull requests are welcome. Please add the link to CorpusTest.java and keep the app free of permissions and libraries.
MIT © biteasier. Includes the AndroidX Custom Tabs AIDL under Apache 2.0, see NOTICE.
Made by biteasier, tutorials on automation and small tools that make life easier.