Skip to content

/mobile-deep-linking-app-links

Deep linking patterns - Universal Links (iOS), App Links (Android), URI schemes, expo-linking API, React Navigation linking config, Expo Router automatic linking, AASA/assetlinks.json setup, deferred deep links, testing

shell
$ npx -y skills add agents-inc/skills --skill mobile-deep-linking-app-links --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/mobile-deep-linking-app-links
How auto-invocation works

Context preview

The summary Claude sees to decide when to auto-load this skill.

Deep linking patterns - Universal Links (iOS), App Links (Android), URI schemes, expo-linking API, React Navigation linking config, Expo Router automatic linking, AASA/assetlinks.json setup, deferred deep links, testing

SKILL.md

mobile-deep-linking-app-links.SKILL.md
name: mobile-deep-linking-app-links
description: Deep linking patterns - Universal Links (iOS), App Links (Android), URI schemes, expo-linking API, React Navigation linking config, Expo Router automatic linking, AASA/assetlinks.json setup, deferred deep links, testing

Deep Linking & App Links Patterns

> **Quick Guide:** Universal Links (iOS) and App Links (Android) are the gold standard -- they use HTTPS URLs that open your app directly or fall back to the website. Custom URI schemes (`myapp://`) are simpler but less reliable (no fallback, can be hijacked). Use `expo-linking` for URL handling (`useURL`, `createURL`, `parse`). Expo Router handles deep linking automatically. React Navigation requires a `linking` config. Always test on real devices -- simulators miss edge cases.

---

<critical_requirements>

CRITICAL: Before Using This Skill

> **All code must follow project conventions in CLAUDE.md** (kebab-case, named exports, import ordering, `import type`, named constants)

**(You MUST use Universal Links (iOS) and App Links (Android) for production apps -- custom URI schemes have no fallback and can be hijacked by other apps)**

**(You MUST host AASA and assetlinks.json over HTTPS at `/.well-known/` -- Apple and Google will reject HTTP or incorrectly hosted files)**

**(You MUST handle all three app states: cold start (app not running), background (app suspended), and foreground (app active) -- missing any state causes dropped links)**

**(You MUST test deep links on real devices -- simulators and emulators do not fully replicate OS-level link handling behavior)**

**(You MUST never pass sensitive data (tokens, passwords) in deep link URLs -- URLs are logged, cached, and visible in browser history)**

</critical_requirements>

---

**Auto-detection:** deep link, deep linking, universal link, app link, URI scheme, custom scheme, expo-linking, Linking.useURL, Linking.createURL, Linking.parse, Linking.openURL, Linking.getInitialURL, linking config, apple-app-site-association, AASA, assetlinks.json, intentFilters, associatedDomains, deferred deep link, App Clip, Instant App, getInitialURL, addEventListener url

**When to use:**

  • Setting up Universal Links (iOS) or App Links (Android) for HTTPS-based deep linking
  • Configuring custom URI schemes for development or simple deep linking
  • Handling incoming URLs across cold start, background, and foreground app states
  • Configuring React Navigation linking config or using Expo Router automatic linking
  • Hosting and validating AASA (iOS) or assetlinks.json (Android) verification files
  • Implementing deferred deep links (link -> store -> install -> content)
  • Testing deep links with CLI tools (`adb`, `xcrun simctl`, `uri-scheme`)

**Key patterns covered:**

  • Universal Links (iOS) and App Links (Android) end-to-end setup
  • Custom URI scheme configuration and handling
  • expo-linking API: `useURL`, `createURL`, `parse`, `getInitialURL`
  • React Navigation `linking` config with path mapping, parameter parsing, nested navigators
  • Expo Router automatic deep linking (zero-config)
  • AASA and assetlinks.json file format, hosting, and validation
  • Handling incoming links in all app states
  • Deferred deep linking concepts and implementation approaches
  • Testing deep links with platform CLI tools

**When NOT to use:**

  • Web-only routing without a native mobile app
  • Push notification routing (handle in your notification skill, not deep linking)
  • App-to-app communication via intents/activities (use your native modules skill)

**Detailed Resources:**

  • [examples/core.md](examples/core.md) - URI schemes, expo-linking API, handling incoming URLs, React Navigation linking config, Expo Router
  • [examples/verification-files.md](examples/verification-files.md) - AASA file (iOS), assetlinks.json (Android), hosting requirements, validation
  • [examples/testing.md](examples/testing.md) - Testing with adb, xcrun simctl, uri-scheme, debugging tips
  • [reference.md](reference.md) - API quick reference, linking config shape, testing commands

---

<philosophy>

Philosophy

Deep linking connects the outside world to specific screens in your app. The goal is a seamless experience: user taps a link, your app opens to the right content. Three link types exist, each with different trade-offs:

1. **Universal Links (iOS) / App Links (Android)** -- HTTPS URLs verified by the OS. App opens directly without disambiguation dialog. Falls back to website if app not installed. **Use these for production.**

2. **Custom URI schemes** (`myapp://path`) -- Simple to set up but unreliable: no fallback if app not installed, any app can register the same scheme (hijacking risk), and some platforms block them. **Use for development or internal tools only.**

3. **Deferred deep links** -- User clicks link, gets sent to app store, installs app, then lands on the intended content. Requires a third-party service or custom server-side logic. **Use when acquisition funnels matter.**

**Key architectural principle:** The link handler is the entry point to your navigation. It must work in all three app states (cold start, background, foreground) and gracefully handle invalid or expired links. Never trust link parameters -- validate and sanitize them before navigating.

**Expo Router vs React Navigation:**

  • **Expo Router** handles deep linking automatically -- every file-based route is a deep link with zero configuration
  • **React Navigation** requires a `linking` config object that maps URL paths to screen names

</philosophy>

---

<patterns>

Core Patterns

Pattern 1: Custom URI Scheme Setup

Configure a custom scheme in your app config so links like `myapp://profile/123` open your app.

{
  "expo": {
    "scheme": "myapp"
  }
}

After adding a scheme, rebuild the app -- scheme changes require a new native build.

**Why good:** Simple to configure, works immediately in development, no server-side setup needed

**Gotcha:** Custom schemes have no fallback --

Read more
Read it on GitHub ↗

Showing the first part of this file.

Ships withagents-inc-skills

The official skills marketplace for Agents Inc. 150+ skills covering everything from React and Prisma to Redis, ElevenLabs, and infrastructure tooling. Pick the skills that match your stack and install them via Claude Code. Need more control?

Get the whole plugin, auto-invoked