Skip to content
Development
Skill

/deep-linking

Deep links, universal links and app links in React Native. Use when links do not open the app, for apple-app-site-association or assetlinks.json, lost cold-start links, expo-router linking, custom URL schemes.

From plugin
claude-code-react-native
318 skills4 agents

Claude Code

$ npx -y skills add AnilBurcu/claude-code-react-native --skill deep-linking --agent claude-code

SKILL.md

deep-linking.SKILL.md
name: deep-linking
description: Deep links, universal links and app links in React Native. Use when links do not open the app, for apple-app-site-association or assetlinks.json, lost cold-start links, expo-router linking, custom URL schemes.
user-invocable: false

Deep links that open the app every time

Two layers, different jobs

  • **Custom schemes** (`myapp://...`): trivial to set up, work from inside your own emails and QR flows, but any app can claim a scheme and browsers treat them as second-class. Fallback layer.
  • **Universal links (iOS) / App links (Android)** (`https://yourdomain.com/...`): the real thing. They need server-side proof files and that is where every setup fails.

Ship both: schemes for internal redirects (OAuth return, payment return), https links for anything a user might tap outside the app.

iOS: the AASA file and Apple's CDN

The proof file lives at `https://yourdomain.com/.well-known/apple-app-site-association`: HTTPS, no redirects, JSON body, appID as `TEAMID.bundleid`. The entitlement side is `applinks:yourdomain.com` (Expo: `associatedDomains` in app config).

The part that costs people days: **devices do not fetch your file directly**. Apple's CDN fetches it (first pickup within about a day) and caches it, so an AASA fix is not live when your server says it is. For development there is an alternate mode: entitlement `applinks:yourdomain.com?mode=developer` plus the device's developer mode skips the CDN. Use it for iteration, remove it for release builds.

If links still open Safari instead of the app: long-press the link and check for the "Open in app" option, confirm the file is reachable with `curl -i` (status 200, no redirect chain), and remember that pasting a URL into Safari's address bar deliberately does NOT trigger universal links; tap one from Notes or Messages instead.

Android: assetlinks.json and the signing key trap

The proof file lives at `https://yourdomain.com/.well-known/assetlinks.json` with the app's package name and the SHA-256 fingerprint of the **certificate that signs what ships**. The trap: with Play App Signing (the norm), Google re-signs your app, so the fingerprint must come from Play Console's App integrity page (the app signing key), NOT from your upload key or local keystore. A local-keystore fingerprint makes verification fail silently and only in production, which is the worst combination.

Add fingerprints additively: dev builds and store builds can both live in the file. Intent filters need `android:autoVerify="true"` on the https filter. Check verification state on a device with:

adb shell pm get-app-links your.package.name

`verified` next to the domain is the goal; anything else names the failing domain.

Cold start vs warm start, the classic lost link

A link that launches the app arrives through the initial-URL path; a link tapped while the app runs arrives through the URL event. Handling only the event listener means cold-start links vanish, and that is the most common deep-link bug report. expo-router handles both when the scheme and domains are configured, but anything custom (auth guards, splash gates, onboarding redirects) must re-apply the pending link AFTER the gate resolves, or the user lands on the home screen and the link dies.

Test both paths explicitly: once with the app killed, once with it backgrounded.

Testing without a website deploy

# custom scheme, both platforms
npx uri-scheme open "myapp://lesson/42" --ios
npx uri-scheme open "myapp://lesson/42" --android

# https links on Android without waiting for verification
adb shell am start -a android.intent.action.VIEW -d "https://yourdomain.com/lesson/42" your.package.name

iOS https links cannot be faked from the terminal in the same way; that is what `mode=developer` exists for.

Adjacent traps

  • OAuth and payment providers redirect back via your scheme or https link; a changed scheme breaks sign-in in the field, so treat the scheme as API surface and never rename it casually.
  • Deferred deep links (install, then first open lands on content) are not a platform feature; they require an attribution/linking service. Do not promise the product team otherwise.
  • Every route a link can open must handle "referenced thing is gone" gracefully; links outlive content.
Read more
@anilburcu
Ships withclaude-code-react-native

Claude knows React. It doesn't know why your pod install just failed. A Claude Code plugin that adds the React Native knowledge you only get from shipping apps: build failure triage, SDK upgrades that don't eat a weekend, Hermes crash decoding, push

318 skills4 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
3
Star history of AnilBurcu/claude-code-react-native on GitHub, a chart by star-history.com

Other skills on claude-code-react-native.

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills13d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react4d252k
@facebook@facebookInstall Skill

Questions about deep-linking.

Which coding agents can use deep-linking?
deep-linking installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.