npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

cordova-plugin-chottulink-sdk

v1.0.0

Published

ChottuLink is your all-in-one solution for creating, managing, and tracking dynamic links across platforms. Boost your marketing campaigns with smart deep linking and comprehensive analytics.

Readme

ChottuLink Cordova SDK

npm version

ChottuLink is an all-in-one solution for creating, managing, and tracking dynamic links across platforms, with smart deep linking and attribution analytics.

This is the Cordova plugin. If you are on Capacitor or Ionic, use capacitor-chottulink-sdk instead; the JavaScript API and all payload shapes are identical between the two.

Features

  • Dynamic Link Creation: create short, trackable links with custom parameters
  • Deep Linking: route users straight to content, including App Links and Universal Links
  • Attribution: know which campaign, source or UTM drove each install
  • Platform-Specific Behavior: control how links behave on iOS and Android
  • Event Listeners: react to deep link resolution, including cold starts
  • Funnel Tracking: identify, leads, conversions and custom events

Requirements

| | Minimum | |---|---| | Cordova CLI | 9.0.0 | | cordova-android | 10.0.0 | | cordova-ios | 6.0.0 | | Android | API 21 (Android 5.0) | | iOS deployment target | 15.6 | | Xcode | 16.2 | | Node.js | 16.x |

Plus a ChottuLink account and an API key.

Installation

cordova plugin add cordova-plugin-chottulink-sdk \
  --variable CHOTTULINK_DOMAIN=yourapp.chottu.link

CHOTTULINK_DOMAIN is the domain serving your links, without a scheme. It is written into the Android App Links intent filter and the iOS Associated Domains entitlement. It is required, because an empty value there fails silently at runtime instead of at build time.

iOS: set the deployment target

This step is required, not optional. cordova-ios 7 generates a project with IPHONEOS_DEPLOYMENT_TARGET = 11.0, well below the framework's 15.6, which produces linker warnings and can crash at launch on older devices. Add this to your project's config.xml:

<platform name="ios">
    <preference name="deployment-target" value="15.6" />
</platform>

Then re-run cordova prepare ios.

iOS: enable Associated Domains on your App ID

The plugin writes the entitlement, but the capability must also be enabled for your App ID in the Apple Developer portal, and your provisioning profile regenerated. Without that, the entitlement is stripped at signing and Universal Links silently stop working.

Getting Started

Everything must happen after Cordova's deviceready event.

1. Initialize the SDK

document.addEventListener('deviceready', function () {
    ChottuLink.initialize({ apiKey: 'your-api-key-here' })
        .then(function () {
            console.log('ChottuLink initialized');
        })
        .catch(function (error) {
            console.error('ChottuLink failed to initialize', error);
        });
}, false);

Subscribe to deep link events before calling initialize. A link that launched the app cold is queued natively and replayed the moment both the SDK and your listeners are ready, so no link is lost, but only if the listener is registered.

2. Handle incoming links

ChottuLink.addListener('onDeepLinkResolved', function (data) {
    console.log('Deep link resolved:', data.url);
    console.log('Metadata:', data.metadata);
    // Route to the right screen in your app
});

ChottuLink.addListener('onDeepLinkFailed', function (data) {
    console.error('Deep link failed:', data.error);
    console.log('Original URL:', data.originalURL);
});

onDeepLinkFailed can fire on an ordinary launch. On a cold start the plugin hands the launch intent (Android) or launch URL (iOS) to the SDK even when it carries no link, because that is what triggers the deferred attribution lookup, the check that matches an install back to the link clicked before the app existed. When there is nothing to match, the SDK reports a failure. Treat this event as informational, not as an error worth surfacing to users: log it, but only navigate on onDeepLinkResolved. This mirrors capacitor-chottulink-sdk.

addListener resolves with a handle you can use to unsubscribe:

const handle = await ChottuLink.addListener('onDeepLinkResolved', onLink);
await handle.remove();

3. Create dynamic links

const result = await ChottuLink.createDynamicLink({
    destinationURL: 'https://example.com/product/123',
    domain: 'yourapp.chottu.link',
    linkName: 'product-link',
    iosBehaviour: ChottuLink.CLDynamicLinkBehaviour.app,
    androidBehaviour: ChottuLink.CLDynamicLinkBehaviour.app,
    socialTitle: 'Check out this product!',
    socialDescription: 'Amazing product description',
    socialImageUrl: 'https://example.com/image.jpg',
    utmSource: 'email',
    utmMedium: 'campaign',
    utmCampaign: 'summer-sale'
});

console.log('Short URL:', result.shortURL);

4. Resolve a link without opening it

const resolved = await ChottuLink.getAppLinkDataFromUrl({
    shortURL: 'https://yourapp.chottu.link/abc123'
});

if (resolved) {
    console.log('Destination:', resolved.link);
    console.log('Deferred?', resolved.isDeferred);
}

Attribution & Analytics

ChottuLink captures install attribution automatically, so you can tell whether a user installed from a link or organically, and which campaign drove it.

const attribution = await ChottuLink.getAttributionData();

if (attribution && attribution.isAttributed) {
    // Always present
    console.log('Attribution type:', attribution.attributionType);
    console.log('Match found:', attribution.matchFound);
    console.log('Is attributed:', attribution.isAttributed);

    // Present only when a match was found; all optional, check before use
    console.log('Install ID:', attribution.installId);
    console.log('Match type:', attribution.matchType);
    console.log('Short URL clicked:', attribution.shortUrl);
    console.log('Short URL (unredirected):', attribution.clickedShortUrl);
    console.log('Destination:', attribution.destinationUrl);
    console.log('Destination with UTM appended:', attribution.destinationWithUtm);
    console.log('Source:', attribution.utmSource);
    console.log('Medium:', attribution.utmMedium);
    console.log('Campaign:', attribution.utmCampaign);
    console.log('Term:', attribution.utmTerm);
    console.log('Content:', attribution.utmContent);
}

Then track the funnel. Every field below except id (for identify) and revenue (for trackConversion) is optional; send only what you have:

// Who the user is; only `id` is required
await ChottuLink.identify({
    id: 'user-42',                   // required
    name: 'Jane Doe',                // optional
    email: '[email protected]',       // optional
    phone: '+15551234567',           // optional
    emailSha256: '<sha256-of-lowercased-email>',  // optional, use instead of `email` if you cannot send it in clear
    phoneSha256: '<sha256-of-e164-phone>'         // optional, use instead of `phone` if you cannot send it in clear
});

// Pre-purchase intent; meta itself is optional, omit it entirely for a bare lead
await ChottuLink.trackLead({
    eventName: 'signup_started',        // optional
    metadata: { plan: 'pro-trial' }     // optional, any JSON-serialisable object
});
await ChottuLink.trackLead();           // also valid: a lead with no metadata at all

// Revenue; only `revenue` is required
await ChottuLink.trackConversion({
    revenue: 499.0,                     // required
    currency: 'INR',                    // optional, ISO 4217 code, e.g. 'USD'
    eventName: 'purchase',              // optional
    productId: 'sku-7',                 // optional
    transactionId: 'txn_1001',          // optional
    metadata: { coupon: 'SUMMER10' }    // optional, any JSON-serialisable object
});

// Anything else; name and data are separate arguments, not one options object
// data is optional and can be omitted entirely
await ChottuLink.trackEvent('added_to_cart', { productId: 'sku-7', quantity: 2 });
await ChottuLink.trackEvent('app_opened');   // also valid: no data

See the Attribution & Analytics docs for more.

Privacy

await ChottuLink.optOut({ enabled: true });   // stop all tracking
const { isOptedOut } = await ChottuLink.isOptedOut();

await ChottuLink.logout();   // clear the identified customer
await ChottuLink.flush();    // send queued events now

TypeScript

Types ship with the plugin:

import type { CLAttributionData, CLDynamicLinkBuilder } from 'cordova-plugin-chottulink-sdk';

const builder: CLDynamicLinkBuilder = {
    destinationURL: 'https://example.com',
    domain: 'yourapp.chottu.link'
};

const { shortURL } = await ChottuLink.createDynamicLink(builder);

Powered by ChottuLink

Drop-in replacement for Firebase Dynamic Links with deferred deep linking, custom domains & real-time analytics.

→ Visit chottulink.com
→ Get Started
→ Try free deep link tester tool
→ Comparison with Branch

Troubleshoot & Test Deep links

For more detailed troubleshooting steps and testing procedures, visit: https://docs.chottulink.com/troubleshooting