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

Deep Linking cu Expo Router: Cum am configurat Universal Links fără să înnebunesc

De Teodor Pascu, 27 apr. 2026 · 1 vizualizări · 3 like-uri

Postat acum 17 ore
json
{
  "expo": {
    "scheme": "my-app-scheme",
    "ios": {
      "bundleIdentifier": "com.company.myapp",
      "associatedDomains": ["applinks:myapp.com"]
    },
    "android": {
      "package": "com.company.myapp",
      "intentFilters": [
        {
          "action": "VIEW",
          "autoVerify": true,
          "data": [
            {
              "scheme": "https",
              "host": "myapp.com",
              "pathPrefix": "/"
            }
          ]
        }
      ]
    }
  }
}

Deep linking-ul e una dintre chestiile alea care par simple în documentație, dar te fac să vrei să-ți schimbi meseria când ajungi la debugging pe device-uri reale. Recent am avut de implementat asta pe un flux de e-commerce unde userul trebuia să ajungă direct într-un ecran de checkout dintr-un email de marketing. Dacă folosești Expo Router, vestea bună e că structura de fișiere îți dictează rutele, deci jumătate din muncă e gata. Vestea proastă? Apple și Google încă au reguli stricte și cache-uri care te scot din minți.

Custom Schemes vs. Universal Links

Prima greșeală pe care o fac mulți e că se opresc la Custom Schemes (numeapp://). E simplu, pui un șir în app.json și gata. Dar schemele astea au un UX oribil: browserul te întreabă de fiecare dată dacă vrei să deschizi aplicația. Pe un proiect cu peste 8k useri activi, am observat că drop-off-ul e masiv când apare popup-ul ăla de sistem.

Universal Links (iOS) și App Links (Android) sunt standardul de aur pentru că folosesc URL-uri de HTTPS. Dacă userul are app-ul, se deschide direct. Dacă nu, ajunge pe site sau în Store. E mult mai fluid, dar necesită o validare între site-ul tău și aplicație prin niște fișiere JSON plasate strategic în folderul .well-known.

Configurarea în Expo Router

Cu Expo Router, totul pleacă de la app.json. Trebuie să definești scheme pentru fallback și associatedDomains pentru iOS. Pe Android, ai nevoie de intentFilters. Am pățit la un moment dat să uit să adaug prefixul applinks: în array-ul de domenii pentru iOS și am pierdut o după-amiază întreagă căutând bug-ul în cod, când de fapt era o simplă eroare de config.

Un aspect critic la Expo Router e că rutele sunt determinate de ierarhia din folderul app/. Dacă ai un fișier app/product/[id].tsx, URL-ul tău universal va trebui să mapreze exact pe structura asta. Avantajul e că nu mai scrii manual logica de linking.config.js din React Navigation, care devenea rapid un coșmar de mentenanță pe măsură ce aplicația creștea.

Partea grea: AASA și AssetLinks

Serverul tău trebuie să servească apple-app-site-association (fără extensie!) pe iOS și assetlinks.json pe Android. Cel mai mare trade-off aici e caching-ul Apple. Când instalezi aplicația, iOS face un request către serverul tău să verifice fișierul AASA. Dacă ai greșit ceva și ai corectat ulterior, Apple s-ar putea să nu mai verifice fișierul ăla timp de 24 de ore.

Pentru debugging, folosiți cu încredere simulatorul, dar testarea finală trebuie făcută pe un device real, cu o variantă de build de tip 'preview' sau 'production'. Pe Android e ceva mai relaxat, poți forța re-indexarea link-urilor din CLI, dar pe iOS ești la mâna lor. Am economisit cam 30% din timpul de testare folosind tool-uri de validare externe înainte să urc fișierele pe serverul de producție.

Cum gestionezi parametrii

În cod, recuperezi datele folosind hook-urile din Expo Router. useLocalSearchParams e sfânt aici. Dacă userul vine de pe https://site.ro/product/123, în componenta ta vei avea ID-ul disponibil imediat. Nu mai ai nevoie de parsări manuale de URL-uri sau regex-uri scrise la 2 dimineața.

Merită efortul? Absolut, dacă vrei o experiență premium. Dacă e doar un MVP intern, rămâi la Custom Schemes și salvează-ți neuronii pentru altceva. Voi cum procedați când Apple refuză să facă refresh la cache-ul de AASA? Folosiți query parameters pentru versionare sau pur și simplu așteptați până a doua zi?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

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