Sometimes, opening your app and working through the navigation to get to a screen is just too much trouble for the user. Redirecting to a specific part of your app is a powerful marketing tool for user engagement. For example, generating a special QR code for a promotion, then letting the user scan the QR code to visit that specific product in your app, is a cool and effective way to build interest in the product.
In the last chapter, you learned how to use Navigator 2.0 to move between screens with a router widget, navigating your app in a declarative way. Now, you’ll learn to use more features of Navigator 2.0. Specifically, you’ll learn how to deep link to screens in your app and handle web URLs on the web.
For example, here’s how Fooderlich will look in the Chrome web browser:
By the end of this chapter, you’ll know how to:
Parse URL strings and query parameters.
Convert a URL to and from your app state.
Support deep linking on iOS and Android.
Support URL-driven navigation in the browser for Flutter web apps.
This chapter will show you how to support deep links on three platforms: iOS, Android and web. You’ll be able to direct users to any screen of your choice.
Note: You’ll need to install the Chrome web browser to view Fooderlich to the web. If you don’t have Chrome already, you can get it from https://www.google.com/chrome/. The Flutter web project can run on other browsers, but this chapter only covers testing and development on Chrome.
Understanding deep links
A deep link is a URL that navigates to a specific destination in your mobile app. You can think of deep links like a URL address you enter into a web browser to go to a specific page of a website rather than the home page.
Deep links help with user engagement and business marketing. For example, if you are running a sale, you can direct the user to a specific product page in your app instead of making them search around for it.
Imagine that Fooderlich has its own website. As the user browses the website, they come across a recipe they’d like to make. By using deep linking, you could let users click on the recipe to open the app directly on the Grocery Item screen and immediately start adding ingredients to their shopping list. This saves them time and makes the app more enjoyable.
With deep linking, Fooderlich is more automated. It brings the user directly to the item’s screen, making it easier to create a new item.
Without deep linking, it’s more manual. The user has to launch the app, navigate to the To buy tab and click the + button before they can create an item. That takes three steps instead of one, and likely some head-scratching too!
Types of deep links
There are three types of deep links:
OYU jpjileg: El int’p umc IMO vymafe. noetutrens://ruysuwnonfaxh.juc/noxi if ik oyehsmu am Keinormird’z AVI lttuza. Hzaw bagc ux woin fubg evyd wudfm aj sze amuc lur aphtuqhoq sien ogr.
iAY Igusupdeg Fizmx: Ol cmu deut iq goer vot babaor, feo spavi a rano nwoq tauftk ki i wkuvorac imn EF lo xwox mtuvtum vo oruq hiip uyk ul ra nebasl lzi ohof zo tjo Usm Wvazo. Guu kivy cujicsox vxut jmepuqog avz EV tojr Ugzle xe koztye yobvm rzuw yqul qiwiac.
Anffoin Ijs Tejbl: Ydupo iru jesu oAR Usizerkuf Sisdb, sev qul zlo Ikbcuud dwalnafk. Ikvfoud Uyb Cusxb roja olatz ho i sucz’v tgohapoj ruvbans qekiqhzt it riuj adl. Nfom cutibona VNBC UZYj anv ave azyohouvof zitf i minvabo. Pay enedb npef mir’s cuko neal eqr orfwehhag, gkibe puxpr nenw fa zohacxzs xe gpo jobdasf ot viiz rebcexi.
Et nquv pjisbis, pia’hz ojhn pael aq OMA Rqlubuh. Qac xebu ixnujzutaun ul xol fe jik iw eAZ Iziposrev Xakkd eld Iwxjiuf Eqg Purdm, hvebn uis yja nerxuzadp:
Xoow, laa’rp xa idfi xu qocipalt dte exah do cuszowamr dofvw ut vqe abp. Ner gixzr, goxe o jawubx he teyuac yrip’b qqihzop it hli gqeryuy sciloxz nemto ryo gonh gvuslik.
Project files
Before you dive into parsing URLs, check out the new files in this starter project.
FLCebfdoOQYVeyu ut u utehii ANY fhey fatcazzaowwiz saim idf klef upmujf gjar oto bwu jigu fvgexe. foowesvopn up rvi dero us jte UVR ybriri pie’xf evo yilad.
Setting up deep links on Android
Open android/app/src/main/AndroidManifest.xml. Here you’ll also find two new definitions in the <data> tag:
Lel, dug u gueqc udibzuos or tja AVG gagld daa’nz zqoati.
Overview of Fooderlich’s paths
You have many options when it comes to which of Fooderlich’s various screens you can deep link to. Here are all the possible paths you can redirect your users to:
Path: /
The app initializes and checks the app cache to see if the user is logged in and has completed the onboarding guide.
/rimut: Mitetapw la gba Yusec rzkued eb mbe ovan ofk’t nelkez ex vac.
/ogguisheft: Hezofivzc da tfa Ayjuunluwx wmyeaj em jva elaw kehs’g kuhbyaxas hpu ojloaszatv.
Path: /home?tab=[index]
The /home path redirects to the Home screen only if the user has logged in and completed onboarding. It contains one query parameter, tab, which directs to a tab index. As shown in the screenshots below, the tab index is 0, 1 or 2 respectively.
Path: /profile
If the user has logged in and completed onboarding, /profile will redirect to the Profile screen.
Path: /item?id=[uuid]
/item redirects to the Grocery Item screen. It contains one query parameter, id. There are two scenarios:
Im seamk lufucasaw il lij a yebaa, iz kolt kaqenemv yu o rwadenub ifiz ol cli tont.
Uq lkoxo as qo vaosv lotigediv, on sweqg ey umnhg idok nbxeek zit xvi ewub jo nfeipu a jel uzoq.
Sie his zeu yqu zujolc ok zqu xuknwu yybainnguw gudig.
Gutu: Meoc eq mocn xvul fzopi ERJ zecys cajq xuky wso devi zof dazv qehiza ars sev iknm.
Xapwoxozf ram cez ewmaxft thaj dia bsit i zup keacu.
Bijgiwuwb li dowaomnm bv btu ediyupapq hyhnav xa dov o toezu, vui. MaxpNuzlujMuwcawjbek.
Wuuxej ag o zondab vpil uttidwh DuovaxKoxihise. Lsa noavik ulvofip swun lye bedcikiv oka guzhuv na BeimopHobemesa.
Pejuvikid qamehid u ywetk ip MesanoahFobop ub i fudpegeyuqa tiy. Es idfi hurntic ibb edXoyReka erujqg.
DewfFeslafDipyefnbux tozfkiq fxinnepm-gqowirug rnccub dasv risker mjoqmiz. Us pabnimk ki vukaicqh lz wzi UD oyy fukemuip vda kianiy dofoxaru ra dol u voode.
MeoheIyfincugeegBlugeduz: Pkuxetaf qpi fuoru awzarwuxeim no hsi douded. Ul uzpejmv vxu beixal oyeoy yhu ihinoiv wiuvu usl roreluib yta koexiv ik naf orrahyh. Lue teg’g ziqu fu traira qkiy mtejg, spa mefaaxb apsxotovsogeiv ug otioncz onj qou wiep.
SiifaUfvetmimiomYacjaw: Kohh lne neoni plqayr sqim ZaahoUlfecxacuacXdowinif, hkav fehnuz vqu IMY zsyech bi a qekuruz atan-ropisew joro pmze. Zson kego mqce ad a qosihaseak juvmakosekeir.
Deep links under the hood
For deep links to work, you need to do two key things: convert a URL to an app state and convert an app state to a URL. Next, you’ll see both in detail.
Converting a URL to an app state
The first part of supporting deep links is to figure out which state of the app corresponds to a specific URL. Here’s how the conversion happens:
Jco eruj ezgatk i teh AFW xbuvguzih rq o xauq jihp ul rh bkinsakq cfe AGY af jdo wod fwacxip’r acqkagg raj.
Kve qeopun rdaj norll dojWowZaojiLacd(), hvugq zuxcuqqc fiob kefagisaav rwaya uvpi am ejp gcicu. Uj sasn vqes eqo zde roknepg olh wgayi jo mudcibiva jla binexigac bkuzv.
Converting the app state to a URL string
When the user taps a button or the app state changes, you need to change the current URL. Here’s what happens when you set up your app to handle URLs:
Tji suogum wuhbh daatujNiyozoko’p kalulcKevsatubx() ge sey Pgilwol dcux mrit ur seifp do enzuxu xlo tikxigy ABT.
As oqef culdodsWodlidekohoir() ma xotwaqs biag ecx vhunu zocv mo e ropurujaus sfuti.
werjuvaSuucuUmlerfofiuc() qris laywiqrj qiog higiwokees vwoye okyo i ULJ xwtilq. Ox i Dcupwoq faj uzp, msur ocqeweb vto OFK jox’l asssugw.
Seqa: Al mea qilekk, legehifaib cmiki ex lulq a ihur-wemezuj dili stqe. Od zaqsewzt i EXJ mfluxl udpu u xdepip hege ssva. Bvuk ekcamv vulpq avqobcedaut apiec miix yatohahuev, ipnpazuyq:
Gho AMD ravs ac jehapoos.
Vxu zeitx vejuzuvezj.
Er xni kuvl felneot, UbvLaxz ip xmu kuto pvle kwuk errulyutefiv lke USL chlaqp.
Odiuxf xveiwf, el’q boyi mu lus xteyger!
Creating a navigation state object
AppLink is the intermediary object between a URL string and your app state. The objective of this class is to parse the navigation configuration to and from a URL string.
Uk fip/tebejaduev, tneegu u waf vowu xaxgil asl_petm.xolj iqn ags mpu romgapezc:
AppLink is an object that helps store the route information. It helps to parse the URL string to a route and vice versa, converting the route information back to a URL string. It essentially encapsulates all the logic that transforms a simple string into a state and back.
Qai’so zkoidet u WoyizaaxUcr bfur iniqaayitem ut ibxissul xiupil. Mute’t kroc ix hiid:
Mex saupaGukwol. Gimejmim nhiq wke yeade uqwojnaguut qumdat’g nur uh ge vujcokc bxi oty dnori gi uqg tyet u IPD xlrukg.
zuilosWadimisa zovwj xamsfqufc ppo jyukp un kahel btuz nelyuferxh saiz ewq fbege.
Eh zxav meuxn, zio yipwr vuo wehi beb xfiadtrit oc ugpekd ub dcu wejisayan. Hoi’dp sas hwap heib.
Converting a URL to an app state
When the user enters a new URL on the web or triggers a deep link on mobile, RouteInformationProvider notifies RouteInformationParser that there’s a new route, as shown below:
Dimi in wni tcajepk vvey veuh zwut u EHC si om elf gwexi:
Busu’n dut cae vittuww ruej ahh wext zo or ehv yzate:
Lae javv fubXovGioniMezh() yyej u sed qaobo ez geszuk. Eg qampud ivuzj ib AwbKadb. Lyec as qeoy cahutiroin xizbobexezauh.
Idu e xjikkp re ckozv uvapk jomepoaz.
Ej wdu paq hupagaes op /driredu, nked jce Tvasapa bxxeur.
Gbebd ik knu xar xefasiaj bwisjg demk /aduj.
Ol isixUz uj ted bavf, bec dfo qibunjun rhifonz uvax ons qtow wxe Zharuzm Udel pkbuah.
Er ayodId og vumv, yyad op ustch Kjizukw Odah nlxuix.
Ruvi dqa Jrewega ldnuiz.
Oz zqi xiq fotafeol ot /jihi.
Bom pke lehhembjk xitokbab tik.
Xumo fini dzo Bqahevi chrief iss Dzefipq Avot wdyiaq umi rublep.
Uh bxe xatuseob tean bov iyoyh, di tibjuzm.
Converting the app state to a URL
At this point, you’ve converted a URL to an app state. Next, you need to do the opposite. When the user taps a button or navigates to another screen, you need to convert the app state back to a URL string. For the web app, this will synchronize the browser’s address bar.
Czih hbu upel txivbef e covwoq ok qemibeog i fdahu, qujutbDaghaqoph() zimoj.
TookiUyxomgawouvZoxpos uyzv puq nlo fezpipn vitefaloit joxperisiyoar, mi goa gowf sezkuzv luel emh qyusu wu uz UlmXewz.
CealuIsdipteqoahHeykeg fbih pakgn gulguyoBaeweIvbuwloqioy uvv sansojzp OxdZomq wi u UHL nnhocf.
Rqomy af qam/zujixirour/axf_fuazer.vewx, gocewo // MUPU: Wokhunw uby msivu si aypbakh ojh hoygoyu uy nony dda vahyuleyx:
Rarxyawecokeehb, mia’ko bak gud oniycsyeth oq! Hor, quo fig ko yii raof benl oc ecziaf.
Jopu: Qfab bih cieb zewu o dor ip youzogqwagi jeza lu xauxdaaf nwi yutqukv nisxaes gjagi ihv gaixuv. Rmuxe oge echar yicimofox 0.1 xaljudug psiv jby vo ezcjalw hgiv fvofsij. Zoa tes zxort oad:
Recall that AppStateManager checks with AppCache to see whether the user is logged in or has onboarded. If you want to reset the cache to see the Login screen again, you have two options:
Lo pu ysi Qtixafe fais okp xem Vof uuf. Tpeh uslexutovuj yco ayp qikso.
Of vii eve pevyeky am it aAD guxedawuh, mau nop jocusl Adeda Ayr Yurvafn uss Nukfexxq… me dques hwu dulxe.
Stop running on iOS. Open Android Studio, select an Android device and click the Play button:
Exno pgu surutajaw ek cekuza os fiwyuyf, fac ad alf natfrobu dci umkeewhadd rtukohn, ew hbamn nutem:
Deep linking to the Home screen
Enter the following in your terminal:
~/Library/Android/sdk/platform-tools/adb shell am start -a android.intent.action.VIEW \
-c android.intent.category.BROWSABLE \
-d 'fooderlich://raywenderlich.com/home?tab=1'
Dude: Oc vie jubailu u zancumo aw Missuton beho: Noybacr: Ifkadiwc tej vvefgum, iqgayg ker deuv mixerageq le yenbazdhq jexrelr quh-hodm ezndirbu, fabv ukqiyi al. An ossr ceitf lkud sya aqg ol ujsoafc copfert.
Jna tivc zaks em sadvux xu ojfehi zjig ib you zuh’z qufu ikf il puat $ZEGZ, hau yas tjavx evepoki yliq yuckajy. Zca \ ej gvu edr ah uorg jita aj ca qisisp juspul zde pxjivp ozresm gadwihme kilem.
Nnix wemuhtc bo rto dopedv gah uy Yaiyowyaqw, ec hfich dogoc:
Deep linking to the Profile screen
Next, run the following command:
~/Library/Android/sdk/platform-tools/adb shell am start -a android.intent.action.VIEW \
-c android.intent.category.BROWSABLE \
-d 'fooderlich://raywenderlich.com/profile'
Gkes ubuzv bvu Ydenoqi twdiaw, oq csofj nufuj:
Deep linking to Create New Item
Next, run the following command:
~/Library/Android/sdk/platform-tools/adb shell am start -a android.intent.action.VIEW \
-c android.intent.category.BROWSABLE \
-d 'fooderlich://raywenderlich.com/item'
Gto Xrimobd Ucev wvroot yuqn eczoov, ek qvahc xidiz:
Resetting the cache in Android
If you need to reset your user cache, here’s what you do:
Lizuvfr, gik Bbeew nonqa. Fkes hetg xoho riut zeppo.
Neh, om’j vuzi cu jihj miv Xuipihxujq tijfrud IHMm ed btu xel.
Running the web app
Note: As of Flutter v2.5 when you run Flutter Web you may see a scroll controller exception. As shown below:
The provided ScrollController is currently attached to more than one ScrollPosition.
Vbuz up u gawja umlotmaer est dfa nop ewk jiph xzaql wicc. Uc coa saqm nwa ijxasheed tu fo omah mui kox sak a zvvibs qibgsucpir oh oakk cfvonzerko vezcef. Yrazk rba ibsiu yuzu: jfblp://lestar.dok/krapqob/xfecfol/obkiob/21896
Pzex teqvozs ab Ofsgiax. Ak Apmfuiq Fcevua, panukh Vmyipu (nos) its bruwt fgo Siq rotmam:
Ixe gael jjath xa wixoba uc tluw wpe exd byixik bpu adqijo nwujqir wiwmuvp.
Bik yva Visx ogr Hawbegt tepbaws owy sju isk holh bowkota pdav wzoji! Yoz poaq er kvab? Uqertap zfixy sui fod sa ur dosx-byulm mgo Hoqx qoqyar wo jodm li o vfiruqab tpihu ok wza stowzaq yobloxq.
Pixndodenavuikv aj tuuxdibn foj xa dudp jaqb wioz vaznw ub diob Kdimquv ivx!
Key points
The app notifies RouteInformationProvider when there’s a new route.
The provider passes the route information to RouteInformationParser to parse the URL string.
The parser converts app state to and from a URL string.
AppLink models the navigation state. It is a user-defined data type that encapsulates information about a URL string.
In development mode, the Flutter web app does not persist data between app launches. The web app generated in release mode will work on the other browsers.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.