@@ -5,11 +5,18 @@ import {
55import { deepViewDataSchema } from "@/lib/zod/schemas/deep-links" ;
66import { prisma } from "@dub/prisma" ;
77import { Grid , Wordmark } from "@dub/ui" ;
8- import { ArrowRight , Copy , IOSAppStore , MobilePhone } from "@dub/ui/icons" ;
8+ import {
9+ AndroidLogo ,
10+ ArrowRight ,
11+ Copy ,
12+ IOSAppStore ,
13+ MobilePhone ,
14+ } from "@dub/ui/icons" ;
915import { cn } from "@dub/utils" ;
1016import { headers } from "next/headers" ;
1117import Link from "next/link" ;
1218import { redirect } from "next/navigation" ;
19+ import { userAgent } from "next/server" ;
1320import { DeepLinkActionButtons } from "./action-buttons" ;
1421import { BrandLogoBadge } from "./brand-logo-badge" ;
1522import { getLanguage , getTranslations } from "./translations" ;
@@ -27,6 +34,10 @@ export default async function DeepLinkPreviewPage(props: {
2734 const language = getLanguage ( acceptLanguage ) ;
2835 const t = getTranslations ( language ) ;
2936
37+ const ua = userAgent ( { headers : headersList } ) ;
38+ const platform : "ios" | "android" =
39+ ua . os ?. name === "Android" ? "android" : "ios" ;
40+
3041 // Encode the key for case-sensitive domains before querying
3142 const encodedKey = encodeKeyIfCaseSensitive ( {
3243 domain,
@@ -46,9 +57,11 @@ export default async function DeepLinkPreviewPage(props: {
4657 shortLink : true ,
4758 url : true ,
4859 ios : true ,
60+ android : true ,
4961 shortDomain : {
5062 select : {
5163 appleAppSiteAssociation : true ,
64+ assetLinks : true ,
5265 deepviewData : true ,
5366 } ,
5467 } ,
@@ -62,10 +75,16 @@ export default async function DeepLinkPreviewPage(props: {
6275
6376 const deepViewData = deepViewDataSchema . parse ( link . shortDomain . deepviewData ) ;
6477
65- // if the link domain doesn't have an AASA file configured (or deepviewData is null)
66- // we skip the deep link preview and redirect to the link's URL
67- if ( ! link . shortDomain . appleAppSiteAssociation || ! deepViewData ) {
68- redirect ( link . ios ?? link . url ) ;
78+ // if the domain isn't set up for deep linking on the user's platform, skip
79+ // the preview and forward to the platform-specific URL (or the canonical URL)
80+ if ( platform === "android" ) {
81+ if ( ! link . shortDomain . assetLinks || ! deepViewData ) {
82+ redirect ( link . android ?? link . url ) ;
83+ }
84+ } else {
85+ if ( ! link . shortDomain . appleAppSiteAssociation || ! deepViewData ) {
86+ redirect ( link . ios ?? link . url ) ;
87+ }
6988 }
7089
7190 // decode the link if the domain is case sensitive
@@ -149,14 +168,22 @@ export default async function DeepLinkPreviewPage(props: {
149168 < div className = "flex items-center justify-center gap-3" >
150169 < Copy className = "text-content-default size-6" />
151170 < ArrowRight className = "text-content-subtle size-3" />
152- < IOSAppStore className = "text-content-default size-6" />
171+ { platform === "android" ? (
172+ < AndroidLogo className = "text-content-default size-6" />
173+ ) : (
174+ < IOSAppStore className = "text-content-default size-6" />
175+ ) }
153176 < ArrowRight className = "text-content-subtle size-3" />
154177 < MobilePhone className = "text-content-default size-6" />
155178 </ div >
156179 </ div >
157180 </ div >
158181
159- < DeepLinkActionButtons link = { link } language = { language } />
182+ < DeepLinkActionButtons
183+ link = { link }
184+ language = { language }
185+ platform = { platform }
186+ />
160187 </ div >
161188 </ div >
162189 </ main >
0 commit comments