This document outlines everything needed to set up a domain for Universal Links, Handoff, and web-based sharing features in Canvas Browser.
canvas-browser.com(primary recommendation)canvasbrowser.appgetcanvas.appusecanvas.com
Any registrar works. Popular options:
- Cloudflare Registrar - Cheapest, at-cost pricing
- Namecheap
- Google Domains (now Squarespace)
- Hover
You need a web server that can:
- Serve static files over HTTPS (required by Apple)
- Serve files from the
/.well-known/path - Return proper
Content-Type: application/jsonheaders
Option A: GitHub Pages (Free)
# Create a repo named: yourdomain.com
# Add CNAME file with your domain
# Enable HTTPS in repo settingsOption B: Cloudflare Pages (Free)
- Automatic HTTPS
- Fast global CDN
- Easy deployment
Option C: Vercel/Netlify (Free tier)
- Simple static site deployment
- Automatic HTTPS
Option D: Your own server
- Any server with HTTPS (nginx, Apache, Caddy)
Create this file at: https://yourdomain.com/.well-known/apple-app-site-association
Important: No .json extension! The file must be named exactly apple-app-site-association
{
"applinks": {
"apps": [],
"details": [
{
"appIDs": [
"XXXXXXXXXX.com.canvas.browser"
],
"components": [
{
"/": "/open/*",
"comment": "Open URL in Canvas"
},
{
"/": "/gentab/*",
"comment": "Open shared GenTab"
},
{
"/": "/share/*",
"comment": "Handle shared content"
}
]
}
]
},
"activitycontinuation": {
"apps": [
"XXXXXXXXXX.com.canvas.browser"
]
},
"webcredentials": {
"apps": [
"XXXXXXXXXX.com.canvas.browser"
]
},
"appclips": {
"apps": []
}
}Find your Team ID at: https://developer.apple.com/account → Membership → Team ID
The server must return these headers for the AASA file:
Content-Type: application/json
location /.well-known/apple-app-site-association {
default_type application/json;
}<Files "apple-app-site-association">
Header set Content-Type "application/json"
</Files>/.well-known/*
Content-Type: application/json
Access-Control-Allow-Origin: *
| Type | Name | Value | Purpose |
|---|---|---|---|
| A | @ | Your server IP | Root domain |
| CNAME | www | yourdomain.com | www subdomain |
| CNAME | _domainconnect | (if using Cloudflare) | Domain verification |
- Add domain to Cloudflare
- Update nameservers at registrar
- Enable "Full (Strict)" SSL mode
- Enable "Always Use HTTPS"
- Go to https://developer.apple.com/account/resources/identifiers
- Select your App ID (com.canvas.browser)
- Enable "Associated Domains" capability
- Save
Add to CanvasBrowser.entitlements:
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:yourdomain.com</string>
<string>activitycontinuation:yourdomain.com</string>
<string>webcredentials:yourdomain.com</string>
</array>Use Apple's validator:
# Check if file is accessible
curl -I https://yourdomain.com/.well-known/apple-app-site-association
# Should return:
# HTTP/2 200
# content-type: application/jsonApple caches AASA files. Check their cached version:
curl "https://app-site-association.cdn-apple.com/a/v1/yourdomain.com"- Build and install app on device
- Send yourself a link:
https://yourdomain.com/open/https://example.com - Tap link - should open in Canvas, not Safari
- Ensure same iCloud account on Mac and iPhone
- Browse in Canvas on Mac
- Check iPhone lock screen for Handoff icon
| URL Pattern | Action |
|---|---|
yourdomain.com/open/{encoded-url} |
Open URL in Canvas |
yourdomain.com/gentab/{id} |
Open shared GenTab |
yourdomain.com/share?url={url}&title={title} |
Add to reading list |
yourdomain.com/search?q={query} |
Search in Canvas |
yourdomain.com/ask?q={question} |
Ask Canvas AI |
https://canvas-browser.com/open/https%3A%2F%2Fwww.apple.com
https://canvas-browser.com/gentab/abc123
https://canvas-browser.com/share?url=https://example.com&title=Example
https://canvas-browser.com/search?q=swift+programming
For users without Canvas installed, create landing pages:
<!DOCTYPE html>
<html>
<head>
<title>Open in Canvas Browser</title>
<meta http-equiv="refresh" content="0; url=https://apps.apple.com/app/canvas-browser/id123456789">
</head>
<body>
<h1>Opening in Canvas Browser...</h1>
<p>Don't have Canvas? <a href="https://apps.apple.com/app/canvas-browser/id123456789">Download it here</a></p>
<p>Or continue to: <a id="fallback-link"></a></p>
<script>
const url = decodeURIComponent(window.location.pathname.replace('/open/', ''));
document.getElementById('fallback-link').href = url;
document.getElementById('fallback-link').textContent = url;
</script>
</body>
</html>- Purchase domain
- Set up HTTPS hosting
- Create and deploy AASA file
- Add Associated Domains entitlement to app
- Test Universal Links on device
- Create fallback web pages
- Verify AASA file via Apple CDN
- Test on multiple devices
- Monitor for any CDN caching issues
- Check AASA syntax: Use JSONLint to validate
- Check HTTPS: Must be valid certificate
- Check Content-Type: Must be
application/json - Wait for Apple CDN: Can take 24-48 hours to update
- Reinstall app: Links are checked at install time
- Check device mode: Links don't work in simulator
- Same iCloud account: Must be logged in on both devices
- Bluetooth enabled: Required for Handoff discovery
- WiFi on same network: Or Bluetooth range
- Handoff enabled: Check System Settings → General → AirDrop & Handoff
- iCloud Keychain enabled: Required for passkey sync
- Correct associated domain: Must match exactly
- HTTPS required: No exceptions
| Item | Annual Cost |
|---|---|
| Domain (.com) | $10-15 |
| Hosting (Cloudflare Pages) | Free |
| SSL Certificate | Free (via Cloudflare/Let's Encrypt) |
| Total | ~$12/year |