Skip to content
Tolinku
Tolinku
Sign In Start Free
Deep Linking · · 4 min read

Deep Linking for Fitness and Health Apps

By Tolinku Staff
|
Tolinku deferred deep linking dashboard screenshot for deep linking blog posts

Fitness apps thrive on sharing and social accountability. A user completes a workout and shares their stats. A friend sends a challenge invitation. A trainer posts a workout program link on social media. A wearable sends a notification with a deep link to the day's activity summary. Every one of these interactions is powered by deep links.

This guide covers deep linking patterns for fitness and health apps. For social sharing strategies, see social sharing for referral programs. For building viral mechanics, see viral mechanics in apps.

Person adjusting fitness smartwatch during workout Photo by Ketut Subiyanto on Pexels

URL Structure

Fitness Content Types

/workouts/{workout-slug}                → workout detail (exercises, sets, reps)
/workouts/{workout-slug}/start          → start the workout immediately
/programs/{program-slug}                → multi-week program overview
/programs/{program-slug}/week/{n}       → specific week of a program
/challenges/{challenge-id}              → challenge detail and leaderboard
/challenges/{challenge-id}/join         → join a challenge directly
/activities/{activity-id}               → completed activity summary
/users/{user-id}/profile                → public profile
/groups/{group-id}                      → fitness group
/groups/{group-id}/join                 → join a group
/plans/{plan-id}                        → meal or workout plan

The most shared content type in fitness apps:

func handleWorkoutDeepLink(_ url: URL) {
    let slug = url.pathComponents[2] // /workouts/{slug}
    let shouldAutoStart = url.pathComponents.last == "start"

    WorkoutService.shared.getWorkout(slug) { workout in
        if shouldAutoStart {
            // Start the workout immediately
            navigateToWorkoutPlayer(workout)
        } else {
            // Show workout details
            navigateToWorkoutDetail(workout)
        }
    }
}

Challenge Invitations

Challenges are the highest-growth deep link category for fitness apps:

"I challenged you to 10,000 steps a day for 30 days! Join here:
https://yourapp.com/challenges/CHAL-ABC123/join?inviter=user-456"
fun handleChallengeJoinDeepLink(uri: Uri) {
    val challengeId = uri.pathSegments.getOrNull(1) ?: return
    val inviterId = uri.getQueryParameter("inviter")

    challengeService.getChallenge(challengeId) { challenge ->
        when (challenge.status) {
            ChallengeStatus.ACTIVE -> {
                // Show challenge details with join button
                showChallengePreview(challenge, invitedBy = inviterId)
            }
            ChallengeStatus.UPCOMING -> {
                showChallengePreview(challenge, invitedBy = inviterId)
                showCountdown(challenge.startsAt)
            }
            ChallengeStatus.ENDED -> {
                showChallengeResults(challenge)
                suggestSimilarChallenges()
            }
        }
    }
}

Challenge Result Sharing

After completing a challenge, share the results:

func shareChallengeResult(_ result: ChallengeResult) {
    let url = URL(string: "https://yourapp.com/challenges/\(result.challengeId)")!

    let message = """
    I completed the \(result.challengeName) challenge! \
    \(result.totalDays) days, \(result.totalSteps) steps. \
    My rank: #\(result.rank) of \(result.totalParticipants).
    """

    let activityVC = UIActivityViewController(
        activityItems: [message, url],
        applicationActivities: nil
    )
    present(activityVC, animated: true)
}

Post-Workout Sharing

The "share your workout" flow is the most organic growth channel for fitness apps:

https://yourapp.com/activities/ACT-789?ref=share

The web fallback shows the activity summary:

<meta property="og:title" content="Morning Run - 5.2 km in 28:15">
<meta property="og:description" content="Average pace: 5:26/km. Elevation gain: 42m. View in [YourApp]">
<meta property="og:image" content="https://yourapp.com/api/activities/ACT-789/card.png">

Generate a visually appealing activity card image dynamically:

// API endpoint: generate activity card image
app.get('/api/activities/:id/card.png', async (req, res) => {
  const activity = await getActivity(req.params.id);

  const card = await generateActivityCard({
    type: activity.type,
    distance: activity.distance,
    duration: activity.duration,
    pace: activity.pace,
    mapSnapshot: activity.mapUrl,
    userName: activity.user.displayName
  });

  res.type('image/png').send(card);
});

Progress Milestone Sharing

Automated sharing prompts at milestones:

"You just hit 100 workouts this year! Share your achievement."
Deep link: https://yourapp.com/achievements/100-workouts-2026

Trainers share their programs via deep links:

"My 12-week strength program is now available:
https://yourapp.com/programs/12-week-strength-foundations"

The deep link should handle:

  1. Free programs: open directly.
  2. Paid programs: show preview with purchase option.
  3. Programs requiring subscription: show subscription CTA.
"Join my live yoga class at 7 AM:
https://yourapp.com/live/yoga-sunrise-session?date=2026-06-26"

Handle pre-class, during-class, and post-class states:

func handleLiveClassDeepLink(_ url: URL) {
    guard let classId = url.pathComponents.last else { return }

    LiveClassService.shared.getClass(classId) { liveClass in
        let now = Date()

        if now < liveClass.startTime.addingTimeInterval(-300) {
            // More than 5 minutes before start
            showClassPreview(liveClass, withCountdown: true)
        } else if now < liveClass.endTime {
            // Class is live or about to start
            joinLiveClass(liveClass)
        } else {
            // Class ended
            if let recording = liveClass.recordingUrl {
                showRecording(recording)
            } else {
                showClassSummary(liveClass)
                suggestUpcomingClasses()
            }
        }
    }
}

Apple Watch and HealthKit

Deep links can trigger workout recording on wearables:

// iPhone app receives deep link, forwards to Watch
func handleWorkoutStartDeepLink(_ url: URL) {
    let workoutSlug = url.pathComponents[2]

    // Load workout data
    WorkoutService.shared.getWorkout(workoutSlug) { workout in
        // Forward to Apple Watch if connected
        if WCSession.default.isWatchAppInstalled {
            WCSession.default.sendMessage(
                ["action": "startWorkout", "workout": workout.toDictionary()],
                replyHandler: nil
            )
        }

        // Also show workout on iPhone
        navigateToWorkoutPlayer(workout)
    }
}

Link from health-related notifications to specific data views:

Push: "Your resting heart rate has been trending down this week"
Deep link: /health/heart-rate?period=7d

Push: "You slept 8 hours last night - your best this month"
Deep link: /health/sleep?date=2026-06-25

Structured Data for Fitness Content

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "ExercisePlan",
  "name": "12-Week Strength Foundations",
  "description": "Build a strong foundation with progressive overload training",
  "exerciseType": "Strength Training",
  "activityDuration": "PT45M",
  "activityFrequency": "4 times per week",
  "potentialAction": {
    "@type": "ViewAction",
    "target": "https://yourapp.com/programs/12-week-strength-foundations"
  }
}
</script>

Tolinku for Fitness Apps

Tolinku handles deep link routing for fitness content. Configure routes like /workouts/:slug, /challenges/:id/join, and /programs/:slug in the Tolinku dashboard. Deferred deep linking preserves challenge invitations and workout links through the install flow, so new users land directly on the shared content after installing.

For the broader deep linking trends, see the future of mobile deep linking.

Get deep linking tips in your inbox

One email per week. No spam.

Ready to add deep linking to your app?

Set up Universal Links, App Links, deferred deep linking, and analytics in minutes. Free to start.