Projects included: - maerchenzauber (NestJS backend + Expo mobile + SvelteKit web + Astro landing) - manacore (Expo mobile + SvelteKit web + Astro landing) - manadeck (NestJS backend + Expo mobile + SvelteKit web) - memoro (Expo mobile + SvelteKit web + Astro landing) This commit preserves the current state before monorepo restructuring. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
8.7 KiB
Universal Links Setup for Character Sharing
Overview
We've implemented universal links for character sharing, replacing the custom scheme maerchenzauber:// with clickable HTTPS URLs that work in WhatsApp, SMS, and all messaging apps.
New sharing URL format:
https://märchen-zauber.de/character/{characterId}/{shareCode}
What Was Implemented
1. Landing Page Route ✅
- File:
landingpage/public/character.html - Type: Static HTML with client-side JavaScript
- Purpose: Web page that displays character preview and deep links into the app
- Features:
- Displays character images and description
- Fetches character data from backend using JavaScript
- "Open in App" button
- Auto-opens app on mobile devices
- Fallback to download page if app not installed
- Works with any static hosting (Netlify, Vercel, Apache, etc.)
2. Backend Public Endpoint ✅
- Endpoint:
GET /characters/public/{id}/{shareCode} - File:
backend/src/character/public-character.controller.ts - Purpose: Fetch character data without authentication using share code
- Security: Share code must match to access character data
3. iOS Universal Links Configuration ✅
- File:
landingpage/public/.well-known/apple-app-site-association - App Configuration:
mobile/app.json- addedassociatedDomains - Domain:
applinks:märchen-zauber.deand punycode version
4. Android App Links Configuration ✅
- File:
landingpage/public/.well-known/assetlinks.json - App Configuration:
mobile/app.json- addedintentFilterswithautoVerify: true - Note: ⚠️ Requires SHA-256 fingerprint update (see below)
5. Mobile Share Button ✅
- File:
mobile/components/character/ShareCharacterButton.tsx - Features:
- Generates share code if none exists
- Saves share code to character
- Uses HTTPS URL for sharing
- Loading state while generating code
6. Deep Link Handlers ✅
- Universal Links:
mobile/app/character/[id]/[shareCode].tsx - Custom Scheme:
mobile/app/share/character/[id].tsx(updated to support share code) - Preview Screen:
mobile/app/character/preview/[characterId].tsx(updated to use public endpoint with share code)
Deployment Checklist
Landing Page Deployment
-
Build the landing page:
cd landingpage npm run build # Creates optimized build in dist/ folder -
Deploy to hosting provider (choose one):
Netlify (Recommended):
netlify deploy --prod --dir=dist- URL rewrites handled automatically by
_redirectsfile
Vercel:
vercel --prod- URL rewrites handled automatically by
vercel.jsonfile
Traditional Hosting (Apache/Nginx):
- Upload entire
dist/folder - Apache:
.htaccesshandles rewrites automatically - Nginx: Add rewrite rules to config (see DEPLOYMENT.md)
- URL rewrites handled automatically by
-
Verify
.well-knownfiles are accessible:# iOS curl https://märchen-zauber.de/.well-known/apple-app-site-association # Android curl https://märchen-zauber.de/.well-known/assetlinks.jsonImportant: These files must be served with
Content-Type: application/json -
Verify character page works:
# Should return HTML (not 404) curl https://märchen-zauber.de/character/test123/abc456
Mobile App Configuration
-
Update Android SHA-256 Certificate Fingerprint
Get your SHA-256 fingerprint from Google Play Console or EAS:
# For EAS builds eas credentials # Or from Google Play Console: # Release > Setup > App integrity > App signing key certificateUpdate
landingpage/public/.well-known/assetlinks.json:{ "sha256_cert_fingerprints": [ "YOUR_ACTUAL_SHA256_FINGERPRINT_HERE" ] } -
Build and Deploy Mobile App
cd mobile # Build for iOS eas build --platform ios --profile production # Build for Android eas build --platform android --profile production # Submit to stores eas submit --platform ios eas submit --platform android
Backend Deployment
-
Deploy Backend Updates
The backend already has the public endpoint. No additional deployment needed if already running.
Verify the endpoint works:
curl https://storyteller-backend-111768794939.europe-west3.run.app/characters/public/{id}/{shareCode}
Testing
Test Universal Links (iOS)
-
Send yourself a message with a character link:
https://märchen-zauber.de/character/abc123/xyz789 -
Tap the link - it should:
- Open the app directly if installed
- Show the landing page if app not installed
-
Verify in Safari:
- Long-press the link
- Should show "Open in Märchenzauber"
Test App Links (Android)
-
Send yourself a message with a character link
-
Tap the link - Android should:
- Ask which app to use (first time)
- Remember your choice
- Open app directly on subsequent taps
-
Verify Auto-Verification:
adb shell pm get-app-links com.memoro.maerchenzauber # Should show "verified" for märchen-zauber.de
Test Share Code Security
- Share a character - should generate a share code
- Try accessing with wrong share code - should fail
- Try accessing without auth but with correct share code - should work
How It Works
Sharing Flow
- User taps "Share Character" button
- App generates random 10-character share code (if none exists)
- App saves share code to character in database
- App opens native share sheet with HTTPS URL
- Recipient receives clickable link in WhatsApp/SMS/etc.
Opening Flow
- User taps HTTPS link
- iOS: Universal link → App opens directly
- Android: App link → App opens directly
- Fallback: Landing page loads → "Open in App" button
- App navigates to character preview with share code
- Character preview fetches character using public endpoint
- User sees character and can import to their library
Security
- Characters require both ID and share code to access
- Share codes are random and unpredictable
- No character data exposed without valid share code
- Users can revoke sharing by changing/removing share code
Troubleshooting
Universal Links Not Working on iOS
- Check
.well-known/apple-app-site-associationis accessible - Verify
associatedDomainsin app.json matches exactly - Re-install app after configuration changes
- Test on physical device (simulator may have caching issues)
App Links Not Working on Android
- Verify
assetlinks.jsonhas correct SHA-256 fingerprint - Check autoVerify is set to true in intent filters
- Clear Android system cache: Settings → Apps → Default apps → Opening links
- May take 24-48 hours for Google to verify
Share Code Not Generated
- Check network connection
- Verify backend
/character/:idPUT endpoint is accessible - Check console logs for errors in ShareCharacterButton
Landing Page Not Loading Character
- Verify backend public endpoint is accessible
- Check share code matches in URL and database
- Ensure CORS is enabled on backend for landing page domain
Files Modified/Created
Landing Page
- ✅
public/character.html(new - static character sharing page) - ✅
public/.well-known/apple-app-site-association(new - iOS universal links) - ✅
public/.well-known/assetlinks.json(new - Android app links, SHA-256 updated) - ✅
public/_redirects(new - Netlify URL rewrites) - ✅
public/.htaccess(new - Apache URL rewrites) - ✅
vercel.json(new - Vercel URL rewrites)
Backend
- ✅
src/character/public-character.controller.ts(updated)
Mobile App
- ✅
app.json(updated iOS/Android configs) - ✅
components/character/ShareCharacterButton.tsx(updated) - ✅
app/character/[id]/[shareCode].tsx(new) - ✅
app/share/character/[id].tsx(updated) - ✅
app/character/preview/[characterId].tsx(updated)
Benefits
✅ Clickable links in WhatsApp, SMS, and all messaging apps ✅ Professional appearance with HTTPS URLs ✅ Link previews with character image and description ✅ Seamless app opening on both iOS and Android ✅ Fallback to web if app not installed ✅ Secure with share code validation ✅ Analytics ready - can track link clicks on landing page
Next Steps
- Deploy landing page with
.well-knownfiles - Update Android SHA-256 fingerprint in assetlinks.json
- Build and submit new app versions to stores
- Test thoroughly on both platforms
- Monitor share links in production
- Consider adding analytics to track sharing effectiveness