platforms
the 22 built-in platforms and what each URL shape opens — plus how to add a platform in one PR.
platforms
The deep-link table (services/redirect/src/platforms.ts) is the core of Zippy. Each
platform is one data object; from it Zippy derives the iOS, Android, and web link forms
uniformly. Zippy ships with these 22:
| Platform | Key | Scheme | Android package | Hosts |
|---|---|---|---|---|
linkedin | linkedin | com.linkedin.android | linkedin.com | |
instagram | instagram | com.instagram.android | instagram.com | |
whatsapp | whatsapp | com.whatsapp | wa.me, api.whatsapp.com | |
reddit | reddit | com.reddit.frontpage | reddit.com, old.reddit.com | |
| Product Hunt | producthunt | producthunt | com.producthunt.hunt | producthunt.com |
| YouTube | youtube | youtube | com.google.android.youtube | youtube.com, m.youtube.com, youtu.be, music.youtube.com |
| TikTok | tiktok | tiktok | com.zhiliaoapp.musically | tiktok.com, vm.tiktok.com, m.tiktok.com |
| X (Twitter) | x | twitter | com.twitter.android | x.com, twitter.com, mobile.twitter.com |
| GitHub | github | https † | com.github.android | github.com |
| Amazon | amazon | com.amazon.mobile.shopping.web | com.amazon.mShop.android.shopping | amazon.com, amzn.to, a.co, amzn.com |
| Spotify | spotify | spotify | com.spotify.music | open.spotify.com, spotify.link |
facebook | fb | com.facebook.katana | facebook.com, m.facebook.com, fb.com, fb.me, fb.watch | |
pinterest | pinterest | com.pinterest | pinterest.com | |
| Threads | threads | barcelona | com.instagram.barcelona | threads.net, threads.com |
| Telegram | telegram | tg | org.telegram.messenger | t.me, telegram.me, telegram.dog |
| Apple Music | apple-music | music | com.apple.android.music | music.apple.com |
| Discord | discord | discord | com.discord | discord.com, discord.gg, discordapp.com |
| Google Maps | google-maps | comgooglemapsurl | com.google.android.apps.maps | maps.google.com |
| App Store | app-store | itms-apps | com.android.vending ‡ | apps.apple.com, itunes.apple.com |
| Play Store | play-store | https † | com.android.vending | play.google.com |
| Snapchat | snapchat | https † | com.snapchat.android | snapchat.com |
| Twitch | twitch | twitch | tv.twitch.android.app | twitch.tv, m.twitch.tv |
† Schemeless (Android-only native open). GitHub, Play Store, and Snapchat register no
custom URL scheme — their apps are reachable only via https App Links (Android) and Universal
Links (iOS). So their "scheme" is https and Zippy hands the app the genuine URL: Android gets
a real native-open; iOS lands on the web page (Universal Links don't fire inside in-app
webviews — the exact gap Zippy exists to close). See the GitHub / Snapchat note below.
‡ App Store is iOS-native by design. itms-apps is a built-in iOS system scheme, so
apps.apple.com links open the App Store app straight from a webview. There is no Apple store on
Android, so those links correctly serve web there (the package shown is inert on the Apple host).
Google Play is the separate play-store row, which opens the Play Store app on Android.
Host matching strips a leading www. and is case-insensitive. A destination whose host no
platform owns is never matched — it simply 301s.
What each URL shape opens
| Platform | URL you shorten | Opens in-app |
|---|---|---|
linkedin.com/in/<user> | that profile | |
linkedin.com/company/<name> | that company page | |
| anything else on linkedin.com | the app (web fallback lands the page) | |
instagram.com/<user> | that profile | |
instagram.com/p/…, /reel/… | the app; web fallback lands the post/reel | |
wa.me/<phone> | a chat with that number | |
api.whatsapp.com/send?phone=<phone>&text=<text> | a chat, prefilled with text | |
reddit.com/r/<sub>, /u/<user>, /user/<user> (and posts under them) | that subreddit / user / post | |
| Product Hunt | producthunt.com/posts/<slug>, /products/<slug> | that post / product |
| YouTube | youtu.be/<id>, youtube.com/watch?v=<id>, youtube.com/shorts/<id> | that video |
youtube.com/channel/<id>, /c/<id> | that channel | |
| TikTok | tiktok.com/@<user> | that profile |
tiktok.com/@<user>/video/<id>, vm.tiktok.com/<code> | the app; web fallback lands the video | |
| X (Twitter) | x.com/<user>/status/<id> | that tweet |
x.com/<user> | that profile | |
| GitHub | github.com/<owner>/<repo>, /<user>, …/issues/<n>, …/pull/<n> | Android: that page in the app |
| (same URLs) | iOS: the browser — no app open (see below) | |
| Amazon | amazon.com/dp/<ASIN>?tag=<id> (and any amazon URL) | that product in the app — the ?tag= affiliate tag stays in the URL (see caveat) |
| Spotify | open.spotify.com/track|album|artist|playlist/<id> | that track / album / artist / playlist |
facebook.com/profile.php?id=<numeric> | that profile (numeric ids only) | |
facebook.com/<anything-else> | that page inside the FB app's own webview | |
pinterest.com/pin/<id> | that pin | |
pinterest.com/<user>, /<user>/<board> | the app; web fallback lands the profile/board | |
| Threads | threads.net/@<user>, threads.com/@<user> | that profile |
…/@<user>/post/<code> | the app; web fallback lands the post | |
| Telegram | t.me/<user>, t.me/<user>/<post> | that channel/user (and post) |
t.me/+<hash>, t.me/joinchat/<hash>, t.me/addstickers/<set> | join invite / sticker set | |
| Apple Music | music.apple.com/<cc>/album|song|playlist/… | that album / song / playlist |
| Discord | discord.gg/<code>, discord.com/invite/<code> | that invite |
discord.com/channels/<guild>[/<channel>] | that channel | |
| Google Maps | maps.google.com/… | that place / map in the app (iOS) |
| App Store | apps.apple.com/…/id<n> | iOS: that app in the App Store |
| (same URL) | Android: the browser — no Apple store | |
| Play Store | play.google.com/store/apps/details?id=<pkg> | Android: that app in the Play Store |
| (same URL) | iOS: the browser — no Play app | |
| Snapchat | snapchat.com/add/<user> | Android: the add-friend screen in the app |
| (same URL) | iOS: the browser — no app open (see below) | |
| Twitch | twitch.tv/<channel> | that channel's stream |
twitch.tv/videos/<id>, twitch.tv/directory/game/<name> | that VOD / that game directory |
GitHub / Play Store / Snapchat: Android-only native open (honest limitation)
These apps have no custom URL scheme — only https App Links (Android) and Universal Links (iOS). Zippy hands the app the real URL:
- Android → a package-targeted
intent://…;scheme=https;package=<pkg>opens the app on that page (repo / PR, Play listing, or Snapchat add-friend screen), with the web URL as the native fallback. A real win. - iOS → there is no custom scheme, and Universal Links do not fire from inside in-app
webviews (Instagram, LinkedIn, …) — which is the exact gap Zippy exists to close. So on iOS
these short links land on the web page in the browser: no worse than a plain tap, but no app
open either. We deliberately do not invent a fake scheme (a wrong scheme would only add a
redirect hop). For Snapchat specifically,
snapchat://exists but only opens the camera — it carries no add-friend username — so there is nothing honest to fire on iOS.
Amazon affiliate tag: opens the app, attribution is Amazon's black box
Amazon's com.amazon.mobile.shopping.web:// scheme loads the full web URL in the app, so a
shortened amazon.com/dp/<ASIN>?tag=<your-id-20> link opens the product in the app with the
?tag= still in the URL. What Zippy cannot promise: whether Amazon attributes that tag for
commission once inside the app — Amazon does not document this, and it's true of every deep-link
method, not just Zippy. If commission matters to you, place a test order through the link and
confirm it in your Associates reporting before relying on it.
Best-effort by design
Where a platform has no reliable in-app scheme for a given content type (Instagram posts, TikTok
videos, vm.* shortlinks), path returns "" — the app opens to its home screen and the web
fallback lands the exact content. Nothing breaks; see how deeplinks
work.
Add a platform (PR guide)
Adding a platform is a small, self-contained PR against services/redirect. You touch two
files: the table and its test.
1. Add one object to PLATFORMS
In services/redirect/src/platforms.ts, append a Platform:
Example:
Zippy derives the iOS (scheme://path), Android (intent://…), and web-fallback forms
from these fields — nothing else in the Worker changes.
2. Add test rows to test/platforms.test.ts
Cover each URL shape your path handles (profile, content, and the app-home fallback), and
run the suite:
Tips
- Verify the scheme on a real device if you can — schemes are undocumented and drift.
If you're unsure, leave a
// ponytail:-style note; the web fallback keeps a wrong scheme safe. - Return
""rather than guessing when a content type has no dependable scheme. An app-home open plus the web fallback beats a broken deep link. - Keep hosts lowercase and without
www.— matching normalizes the request host the same way.