Skip to content

Commit 6345b99

Browse files
committed
fix: prioritize web fallback over app store URL in redirect handler
Web fallback URLs take priority over store URLs for iOS and Android. When the fallback is on the app's Universal Link / App Link domain, the OS opens the app directly. If the app isn't installed, the fallback page shows store download links. Previously, the store URL was checked first, sending users to the App Store even when the app was already installed.
1 parent 760eb3b commit 6345b99

1 file changed

Lines changed: 19 additions & 14 deletions

File tree

src/routes/redirect.ts

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -273,12 +273,15 @@ export async function redirectRoutes(fastify: FastifyInstance) {
273273
} else if (link.app_scheme && link.deep_link_path) {
274274
redirectUrl = `${link.app_scheme}://${link.deep_link_path.replace(/^\//, '')}`;
275275
redirectReason = 'app_scheme';
276-
} else if (iosStoreUrl) {
277-
redirectUrl = iosStoreUrl;
278-
redirectReason = 'ios_app_store_url';
279276
} else if (webFallback) {
277+
// Web fallback takes priority over store URL — if the fallback is on
278+
// the app's Universal Link domain, iOS will open the app directly.
279+
// If the app isn't installed, the fallback page shows store links.
280280
redirectUrl = webFallback;
281281
redirectReason = 'web_fallback_url';
282+
} else if (iosStoreUrl) {
283+
redirectUrl = iosStoreUrl;
284+
redirectReason = 'ios_app_store_url';
282285
}
283286
} else if (deviceType === 'android') {
284287
if (link.android_app_link) {
@@ -287,12 +290,12 @@ export async function redirectRoutes(fastify: FastifyInstance) {
287290
} else if (link.app_scheme && link.deep_link_path) {
288291
redirectUrl = `${link.app_scheme}://${link.deep_link_path.replace(/^\//, '')}`;
289292
redirectReason = 'app_scheme';
290-
} else if (androidStoreUrl) {
291-
redirectUrl = androidStoreUrl;
292-
redirectReason = 'android_app_store_url';
293293
} else if (webFallback) {
294294
redirectUrl = webFallback;
295295
redirectReason = 'web_fallback_url';
296+
} else if (androidStoreUrl) {
297+
redirectUrl = androidStoreUrl;
298+
redirectReason = 'android_app_store_url';
296299
}
297300
} else if (deviceType === 'web' && webFallback) {
298301
redirectUrl = webFallback;
@@ -392,8 +395,9 @@ export async function redirectRoutes(fastify: FastifyInstance) {
392395
// iOS Priority:
393396
// 1. Universal Link (HTTPS URL with AASA file) - if app installed, opens app
394397
// 2. URI scheme (myapp://path) - fallback when Universal Links fail
395-
// 3. App Store URL (link → template → workspace) - for users who don't have the app
396-
// 4. Web fallback URL - browser-based fallback
398+
// 3. Web fallback URL - if on the app's Universal Link domain, iOS opens the app;
399+
// if app isn't installed, the page shows store download links
400+
// 4. App Store URL (link → template → workspace) - direct store redirect
397401
// 5. Original URL - ultimate fallback
398402

399403
if (link.ios_universal_link) {
@@ -402,18 +406,19 @@ export async function redirectRoutes(fastify: FastifyInstance) {
402406
// Build URI scheme URL: myapp://product/123
403407
redirectUrl = `${link.app_scheme}://${link.deep_link_path.replace(/^\//, '')}`;
404408
useSchemeUrl = true;
405-
} else if (iosUrl) {
406-
redirectUrl = iosUrl;
407409
} else if (webFallbackUrl) {
408410
redirectUrl = webFallbackUrl;
411+
} else if (iosUrl) {
412+
redirectUrl = iosUrl;
409413
}
410414

411415
} else if (device === 'android') {
412416
// Android Priority:
413417
// 1. App Link (HTTPS URL with Digital Asset Links) - if app installed, opens app
414418
// 2. URI scheme (myapp://path) - fallback when App Links fail
415-
// 3. Play Store URL (link → template → workspace) - for users who don't have the app
416-
// 4. Web fallback URL - browser-based fallback
419+
// 3. Web fallback URL - if on the app's App Link domain, Android opens the app;
420+
// if app isn't installed, the page shows store download links
421+
// 4. Play Store URL (link → template → workspace) - direct store redirect
417422
// 5. Original URL - ultimate fallback
418423

419424
if (link.android_app_link) {
@@ -422,10 +427,10 @@ export async function redirectRoutes(fastify: FastifyInstance) {
422427
// Build URI scheme URL: myapp://product/123
423428
redirectUrl = `${link.app_scheme}://${link.deep_link_path.replace(/^\//, '')}`;
424429
useSchemeUrl = true;
425-
} else if (androidUrl) {
426-
redirectUrl = androidUrl;
427430
} else if (webFallbackUrl) {
428431
redirectUrl = webFallbackUrl;
432+
} else if (androidUrl) {
433+
redirectUrl = androidUrl;
429434
}
430435

431436
} else if (device === 'web') {

0 commit comments

Comments
 (0)