All skills
davidortinau avatar

/maui-deep-linking

@542317e

Guide for implementing deep linking in .NET MAUI apps. Covers Android App Links with intent filters, Digital Asset Links, and AutoVerify; iOS Universal Links with Associated Domains entitlements and Apple App Site Association files; custom URI schemes; and domain verification for both platforms. USE FOR: "deep linking", "app links", "universal links", "custom URI scheme", "intent filter", "Associated Domains", "Digital Asset Links", "open app from URL", "handle incoming URL", "domain verification". DO NOT USE FOR: in-app Shell navigation (use maui-shell-navigation), push notification handling (use maui-push-notifications), or web content embedding (use maui-hybridwebview).

Use this Skill: https://skilld.dev/gh/davidortinau/maui-skills/maui-deep-linking

This session only. Nothing lands on disk.

referencesdeep-linking-api.md

≈953 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Deep Linking API Reference

Android App Links

IntentFilter on MainActivity

[IntentFilter(
    new[] { Android.Content.Intent.ActionView },
    Categories = new[] {
        Android.Content.Intent.CategoryDefault,
        Android.Content.Intent.CategoryBrowsable
    },
    DataScheme = "https",
    DataHost = "example.com",
    DataPathPrefix = "/products",
    AutoVerify = true)]
public class MainActivity : MauiAppCompatActivity { }

Stack multiple IntentFilter attributes for different paths.

Digital Asset Links (domain verification)

Host /.well-known/assetlinks.json on your domain over HTTPS:

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example.myapp",
    "sha256_cert_fingerprints": ["AA:BB:CC:..."]
  }
}]

Get SHA-256: keytool -list -v -keystore my-release-key.keystore -alias alias_name

Handle incoming intents

protected override void OnCreate(Bundle? savedInstanceState)
{
    base.OnCreate(savedInstanceState);
    HandleDeepLink(Intent);
}

protected override void OnNewIntent(Intent? intent)
{
    base.OnNewIntent(intent);
    HandleDeepLink(intent);
}

void HandleDeepLink(Intent? intent)
{
    if (intent?.Action != Intent.ActionView || intent.Data is null) return;
    Shell.Current.GoToAsync(MapToRoute(intent.Data.ToString()!));
}

Test commands

adb shell am start -W -a android.intent.action.VIEW \
  -d "https://example.com/products/42" com.example.myapp
adb shell pm get-app-links com.example.myapp

iOS Universal Links

Associated Domains entitlement

In Entitlements.plist:

<key>com.apple.developer.associated-domains</key>
<array>
    <string>applinks:example.com</string>
</array>

Apple App Site Association file

Host at /.well-known/apple-app-site-association (Content-Type: application/json):

{
  "applinks": {
    "details": [{
      "appIDs": ["TEAMID.com.example.myapp"],
      "components": [{ "/": "/products/*" }]
    }]
  }
}

Handle Universal Links in MAUI

builder.ConfigureLifecycleEvents(events =>
{
#if IOS || MACCATALYST
    events.AddiOS(ios =>
    {
        ios.FinishedLaunching((app, options) =>
        {
            var activity = options?[UIKit.UIApplication.LaunchOptionsUniversalLinkKey]
                as Foundation.NSUserActivity;
            HandleUniversalLink(activity?.WebPageUrl?.ToString());
            return true;
        });
        ios.ContinueUserActivity((app, activity, handler) =>
        {
            if (activity.ActivityType == Foundation.NSUserActivityType.BrowsingWeb)
                HandleUniversalLink(activity.WebPageUrl?.ToString());
            return true;
        });
        ios.SceneWillConnect((scene, session, options) =>
        {
            var activity = options.UserActivities?
                .ToArray<Foundation.NSUserActivity>()
                .FirstOrDefault(a =>
                    a.ActivityType == Foundation.NSUserActivityType.BrowsingWeb);
            HandleUniversalLink(activity?.WebPageUrl?.ToString());
        });
    });
#endif
});

static void HandleUniversalLink(string? url)
{
    if (string.IsNullOrEmpty(url)) return;
    MainThread.BeginInvokeOnMainThread(async () =>
        await Shell.Current.GoToAsync(MapToRoute(url)));
}

Shell Navigation Integration

// Register in AppShell constructor
Routing.RegisterRoute("products/detail", typeof(ProductDetailPage));

static string MapToRoute(string uri)
{
    var segments = new Uri(uri).AbsolutePath.Trim('/').Split('/');
    return segments switch
    {
        ["products", var id] => $"products/detail?id={id}",
        ["settings"] => "settings",
        _ => "//"
    };
}

Source: SKILL.md on GitHub

No alerts15d4 checks · Risk SAFE
  • Gen Agent Trust Hub15d

    The skill provides implementation details for .NET MAUI deep linking. It includes an entry point for untrusted data via external URLs and provides instructions for executing command-line testing tools.

  • Socket15d

    No alerts

  • Snyk15d

    Risk: LOW · No issues

  • Runlayer7mo

    1/1 file flagged

Signed by skilld at 542317e. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Steadyupdated 6 months ago

README badge

README badge for davidortinau/maui-skills/maui-deep-linking