npx skills add smithery/evanbacon --skill universal-links
evanbacon/evanbacon.dev · Archived
universal-links
Set up and test universal links for iOS using setup-safari
Installation
npx skills add evanbacon/evanbacon.dev --skill universal-links
Stronger alternatives
This repository is archived — consider an actively maintained alternative.
Build a production-quality chat UI with keyboard handling, recycling lists, gestures, and platf…
12 installsUse when you need to achieve any emotional outcome through animation—provides a framework for m…
412 installsUse when discussing animation principles with users of unknown skill level, or when providing a…
400 installsUse when creating any animation type - provides foundational timing, easing, and principle appl…
395 installsSimilar popular skills
Related neighbors and high-traction skills in the same topics — useful to compare before installing.
Browser automation CLI for AI agents. Use when the user needs to interact with websites, includ…
810.4K installsDebug Azure production issues on Azure using AppLens, Azure Monitor, resource health, and safe …
568.9K installsPre-deployment validation for Azure readiness. Run deep checks on configuration, infrastructure…
567.7K installsConfigure Azure API Management as an AI Gateway for AI models, MCP tools, and agents. WHEN: sem…
566.3K installsAzure VM/VMSS router. WHEN: create / provision / deploy / spin-up VM, recommend VM size, compar…
510K installsPostgres best practices maintained by Supabase, for Postgres running anywhere. Load this skill …
391.6K installsAlso in this package
Other skills from evanbacon/evanbacon.dev.
npx skills add evanbacon/evanbacon.dev
More details
Agent compatibility
Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.
Also listed on
Alternate registries and mirrors of this skill.
Repository health
main
Package contents
Files included with this skill beyond the listing page.
-
skill md
SKILL.md5,623 B -
docs
SUMMARY.md81 B
History
- First seen on skills.sh
- First recorded snapshot · 3 installs
SKILL.md
Use bunx setup-safari to configure and test universal links (deep links) on iOS.
Important: When Custom Builds Are Needed
Universal links with custom domains require custom native builds. Your app will no longer work in Expo Go.
However, for basic deep linking during development:
- Expo Go supports the
exp://URL scheme and Expo-hosted URLs - Custom builds required for your own domain's universal links (applinks:yourdomain.com)
If you only need deep linking for development/testing, try npx expo start with Expo Go first. Only create custom builds when you need production universal links with your own domain.
Automated Setup (Recommended)
Run setup-safari with your Apple ID to automate credential lookup:
EXPO_APPLE_ID="[email protected]" bunx setup-safari
This will:
- Authenticate with Apple Developer Portal
- Enable Associated Domains for your bundle ID
- Output the AASA file content and meta tag
After running, you must manually:
1. Create the AASA file
Create public/.well-known/apple-app-site-association (no file extension):
{
"applinks": {
"details": [
{
"appIDs": ["TEAM_ID.com.your.bundleid"],
"components": [
{
"/": "*",
"comment": "Matches all routes"
}
]
}
]
},
"activitycontinuation": {
"apps": ["TEAM_ID.com.your.bundleid"]
},
"webcredentials": {
"apps": ["TEAM_ID.com.your.bundleid"]
}
}
2. Create src/app/+html.tsx with Smart App Banner
import { ScrollViewStyleReset } from "expo-router/html";
export default function Root({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<meta name="apple-itunes-app" content="app-id=YOUR_ITUNES_ID" />
<ScrollViewStyleReset />
</head>
<body>{children}</body>
</html>
);
}
3. Add Associated Domains to app.json
{
"expo": {
"ios": {
"associatedDomains": [
"applinks:yourdomain.com",
"activitycontinuation:yourdomain.com",
"webcredentials:yourdomain.com"
]
}
}
}
4. Deploy and Rebuild
# Deploy web (AASA file must be accessible)
npx expo export -p web && npx eas-cli deploy
# Rebuild iOS app with new entitlements
npx expo run:ios
# Or for TestFlight: npx testflight
Interactive Setup (Alternative)
For interactive mode (requires TTY):
bunx setup-safari
How Universal Links Work
Universal links require two parts:
- AASA file on your server - Tells iOS which paths your app handles
- Associated Domains entitlement - Tells your app which domains to claim
AASA File Format
Host at https://yourdomain.com/.well-known/apple-app-site-association:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "TEAM_ID.com.example.app",
"paths": ["*"]
}
]
}
}
Path patterns:
*- Match all paths/products/*- Match paths starting with /products//item/???- Match exactly 3 characters after /item/NOT /admin/*- Exclude paths
Associated Domains Entitlement
In your app.json or app.config.js:
{
"expo": {
"ios": {
"associatedDomains": [
"applinks:yourdomain.com",
"applinks:www.yourdomain.com"
]
}
}
}
Testing Universal Links
After setup, test with setup-safari:
npx setup-safari
Or manually test in Safari:
- Open Safari on iOS device/simulator
- Navigate to a URL that should open your app
- Pull down to reveal the banner, or long-press the link
Testing with Tunnel (No Server Required)
Test universal links without deploying a website using Expo's tunnel feature:
- Set a consistent tunnel subdomain:
export EXPO_TUNNEL_SUBDOMAIN=my-app-name
- Configure associated domains with the ngrok URL:
{
"expo": {
"ios": {
"associatedDomains": ["applinks:my-app-name.ngrok.io"]
}
}
}
- Build the development client:
npx expo run:ios
- Start the dev server with tunnel:
npx expo start --tunnel
- Test the link - Type
https://my-app-name.ngrok.ioin Safari on your device. It should open your app directly.
The tunnel creates a public HTTPS URL that serves the AASA file automatically, letting you test the full universal links flow during development.
Debugging
Check if Apple has cached your AASA:
curl "https://app-site-association.cdn-apple.com/a/v1/yourdomain.com"
Validate AASA file format:
curl https://yourdomain.com/.well-known/apple-app-site-association | jq
Common issues:
- AASA must be served with
Content-Type: application/json - HTTPS required (no self-signed certs)
- Apple caches AASA files - changes may take time to propagate
Expo Router Integration
With Expo Router, handle incoming links automatically:
// app/[...path].tsx handles all deep link paths
// app/products/[id].tsx handles /products/:id links
Access link parameters:
import { useLocalSearchParams } from "expo-router";
export default function Product() {
const { id } = useLocalSearchParams();
return <Text>Product: {id}</Text>;
}