eduardweb.
Navigație & StateAvansat#react-native#android#ios#deep-linking#expo-router

Deep linking universal cu Expo Router: cum setezi Universal Links și App Links fără nervi

De Alin Pătrașcu, 2 oct. 2026 · 14 vizualizări · 3 like-uri

Postat 2 oct. 2026
json
{
  "expo": {
    "name": "FintechApp",
    "slug": "fintech-app",
    "scheme": "fintechapp",
    "ios": {
      "bundleIdentifier": "ro.eduardweb.fintech",
      "associatedDomains": [
        "applinks:eduardweb.ro"
      ]
    },
    "android": {
      "package": "ro.eduardweb.fintech",
      "intentFilters": [
        {
          "action": "VIEW",
          "autoVerify": true,
          "data": [
            {
              "scheme": "https",
              "host": "eduardweb.ro",
              "pathPrefix": "/invite"
            }
          ],
          "category": ["BROWSABLE", "DEFAULT"]
        }
      ]
    }
  }
}

Toată lumea crede că deep linking-ul e rezolvat din oficiu când treci pe Expo Router, fiindcă rutele din folderul app/ se mapează 1:1 pe structura URL-urilor web. Parțial adevărat, dar până ajungi la un click din WhatsApp sau dintr-un mail care să deschidă direct ecranul dorit fără să treacă prin browser, ai de trecut prin furcile caudine ale Apple și Google.

La un proiect fintech cu vreo 12k de useri activi zilnic, am avut de migrat de la React Navigation clasic la Expo Router. Totul a mers brici pe emulatoare cu scheme-ul personalizat myapp://, dar în producție, 40% din useri rămâneau blocați pe pagina web de fallback.

Custom Scheme vs Universal/App Links: capcana securității

Custom schemes (myapp://checkout/123) sunt bune doar pentru debugging local. Nu le folosi ca mecanism principal în producție. Pe Android, orice aplicație malițioasă poate înregistra același custom scheme în Manifest și să intercepteze tokeni de autentificare sau parametri sensibili.

Universal Links (iOS) și Android App Links (Android 6.0+, dar strict verificate începând cu Android 12) rezolvă asta prin asocierea criptografică a aplicației cu domeniul tău web prin două fișiere statice servite peste HTTPS:

  • https://domeniul-tau.ro/.well-known/apple-app-site-association (fără extensie .json pe iOS)
  • https://domeniul-tau.ro/.well-known/assetlinks.json

Configurația în app.json

Expo Router simplifică enorm codul din JavaScript fiindcă nu mai scrii manual un config stufos de linking: { prefixes: [...], config: { screens: ... } }. Routerul se ocupă singur de parsing. În schimb, trebuie să spui compilatorului nativ ce domenii să intercepteze.

Pe iOS adaugi associatedDomains cu prefixul applinks:. Pe Android ai nevoie de un intentFilter cu autoVerify: true — dacă uiți flag-ul ăsta pe Android 12+, sistemul nici măcar nu încearcă să verifice fișierul assetlinks.json și deschide direct Chrome.

Capcane mari la fișierele de pe server

Am pierdut două zile întregi pe un issue aparent inexplicabil pe iOS: Universal Links mergeau pe telefoanele noastre de dev, dar pe telefoanele din TestFlight dădeau fail. De ce? Apple trece cererile pentru fișierul AASA printr-un CDN propriu de cache. Dacă serverul tău web returnează un redirect (301 sau 302 de la HTTP la HTTPS, sau de la www. la non-www), CDN-ul Apple renunță instant.

Reguli obligatorii pentru server:

  • Returnează fișierele cu status 200 OK direct, fără redirect.
  • Header-ul Content-Type pentru iOS trebuie să fie strict application/json (chiar dacă fișierul fizic nu are extensie).
  • Pe Android, generează SHA-256 fingerprint-ul corect. Dacă folosești Google Play App Signing, fingerprint-ul cheii de upload e diferit de fingerprint-ul cheii finale cu care Google semnează bundle-ul în store. Trebuie să adaugi ambele amprente în assetlinks.json.

Cum testezi fără să trimiți în producție

Pentru Android, poți forța reverificarea domeniului prin ADB fără să reinstalezi app-ul: adb shell pm verify-app-links --re-verify com.numepachet

După comandă, verifică statusul cu adb shell pm get-app-links com.numepachet. Dacă vezi status verified, ești safe. Dacă vezi 1024 sau legacy_failure, domeniul nu răspunde corect sau certificatul SSL are probleme.

Trade-off-ul sincer: efortul de DevOps pentru server și semnături e de 3 ori mai mare decât scrierea codului de routing în sine. Merită efortul? Categoric da, conversia la link-urile de referral a crescut la noi cu 22% din prima săptămână.

Voi cum ați rezolvat verificarea domeniilor în mediile de staging unde domeniile sunt parolate cu Basic Auth?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

Doar membrii comunității pot lăsa comentarii.