Skip to main content

linksapp 0.2.0 copy "linksapp: ^0.2.0" to clipboard
linksapp: ^0.2.0 copied to clipboard

Flutter Universal Link and App Link handling for LinksApp.

LinksApp Flutter SDK #

Receive verified iOS Universal Links and Android App Links, resolve them through LinksApp, and route users to the destination in your Flutter app. The package also exposes LinksAppClient if your app already receives URLs another way.

LinksApp URLs have these forms:

https://<app-key>.linksapp.me
https://<app-key>.linksapp.me/<sublink-code>

Every app gets its own host. The domain in your app configuration must match the host of the URL people tap, so for app key daily-pooja use daily-pooja.linksapp.me on both iOS and Android. Your iOS Bundle ID is not the applinks: domain; register the Bundle ID and Apple Team ID in the LinksApp console so they appear in the association file served by your app's host. Likewise, register your Android package name and signing certificate SHA-256 fingerprint for Android verification. A customer-owned domain would need its own association files and custom-domain support in the LinksApp service and SDK; simply replacing linksapp.me in these snippets will not make that domain work.

Upgrading from 0.1.x: links moved from https://linksapp.me/a/<app-key> to https://<app-key>.linksapp.me. Update the Android intent filter and iOS Associated Domains below, then ship a new build: old path links are no longer served.

Install #

flutter pub add linksapp

Create an App Link in the LinksApp console, then copy its app key. Register your iOS Team ID and Bundle ID, or your Android package name and release SHA-256 signing fingerprint. The app key in the URL must match the key passed to the SDK.

The SDK does not claim the domain for your app. Complete the native setup below before testing an installed-app link.

Native setup #

Android #

Add an App Link filter to the activity that hosts Flutter. Replace YOUR_APP_KEY with the app key from the LinksApp console:

<!-- android/app/src/main/AndroidManifest.xml, inside MainActivity -->
<meta-data android:name="flutter_deeplinking_enabled" android:value="false" />

<intent-filter android:autoVerify="true">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="https"
          android:host="YOUR_APP_KEY.linksapp.me" />
</intent-filter>

The whole host belongs to your app, so no path is needed. LinksApp serves the host's assetlinks.json using the package name and release fingerprint you registered. Use the Play App Signing certificate fingerprint for a Play-distributed app.

iOS #

Add Associated Domains to your app target in Xcode:

applinks:YOUR_APP_KEY.linksapp.me

Also disable Flutter's built-in deep-link handler so it does not compete with the SDK's app_links receiver:

<!-- ios/Runner/Info.plist, inside dict -->
<key>FlutterDeepLinkingEnabled</key>
<false/>

LinksApp serves the host's Apple App Site Association file using the Team ID and Bundle ID you registered. After changing association settings, reinstall the app before testing; the operating system may cache the earlier file.

Check that https://YOUR_APP_KEY.linksapp.me/.well-known/apple-app-site-association lists your TEAM_ID.BUNDLE_ID. The app target's Associated Domains capability must contain applinks:YOUR_APP_KEY.linksapp.me (no https:// prefix and no URL path).

Huawei phones (AppGallery) #

Huawei phones that run Android apps (EMUI, HarmonyOS 2–4) use the same Android setup above; no extra plugin is needed. Two things differ:

  • Signing certificate. If AppGallery re-signs your app (AppGallery Connect → App signing), the copy installed from AppGallery has a different certificate from the Play copy. Add its SHA-256 to the app link's fingerprints in the LinksApp console, or App Link verification fails on those phones.
  • Store fallback. Save your AppGallery app ID in the console. The browser landing page then offers AppGallery (first on Huawei browsers), and the resolver returns it as result.huaweiFallback.

HarmonyOS NEXT (5.x) runs only native HarmonyOS apps and is not supported by this package.

Create one listener near your app router. Start it once and dispose it when its owner is torn down:

import 'package:linksapp/linksapp.dart';

late final LinksApp linksApp;

Future<void> startLinks() async {
  linksApp = LinksApp(
    appKey: 'your-app-key',
    onResolved: (result) {
      // Use your own router to open the destination inside the app.
      router.open(result.deepLink, referral: result.ref);
    },
    onError: (error, stackTrace) {
      // Display or log malformed links and resolver failures.
      reportLinkError(error, stackTrace);
    },
  );
  await linksApp.start();
}

Future<void> stopLinks() => linksApp.dispose();

start() handles both the initial URL and subsequent URL events, suppressing the common duplicate initial delivery. result.deepLink is the destination you should route to; result.ref contains optional referral context. The SDK does not navigate automatically because each app has its own router.

See the example app for a complete Flutter widget.

Resolve a URL directly #

If your app already receives Universal Links or App Links, you can use the resolver without LinksApp:

final client = LinksAppClient(expectedAppKey: 'your-app-key');
try {
  final result = await client.resolve(incomingUri);
  router.open(result.deepLink, referral: result.ref);
} finally {
  client.close();
}

resolve() throws FormatException for an invalid URL or response. It throws LinksAppException for an API error; check statusCode to distinguish an unknown link (404) from a disabled, expired, or exhausted link (410). The expected app key prevents your app from resolving another customer's link.

If you used LinksAppFlutter in an earlier release, it remains available as a deprecated alias. Change the class name to LinksApp when convenient; the constructor and behavior are the same.

Testing and limitations #

  • Test an installed iOS app by tapping a link from Notes or Messages. Typing it into Safari's address bar is not a Universal Link test.

  • Test an installed Android app with a tapped link, or run:

    adb shell am start -a android.intent.action.VIEW \
      -c android.intent.category.BROWSABLE \
      -d 'https://YOUR_APP_KEY.linksapp.me'
    adb shell pm get-app-links YOUR_ANDROID_PACKAGE
    

    If Android opens the browser, check the verification state, the registered signing fingerprint, and https://YOUR_APP_KEY.linksapp.me/.well-known/assetlinks.json.

  • An uninstalled app opens the LinksApp browser fallback with store buttons. Universal Links alone cannot automatically restore a link after a first-time iOS App Store install.

  • Do not put a sublink-creation API key in a mobile app. Create sublinks from a trusted server.

For dashboard setup, device testing, and API details, see the LinksApp integration guide.

0
likes
160
points
133
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Flutter Universal Link and App Link handling for LinksApp.

Homepage

License

MIT (license)

Dependencies

app_links, flutter, http

More

Packages that depend on linksapp