Clipboard-Based DDL is a solution by Singular that takes advantage of the clipboard feature in the user's mobile device to:
- Attributing mobile web-to-app installs in a deterministic manner
- Enable deep linking and deferred deep linking (DDL).
FAQ
How does Clipboard-Based DDL work?
The flow for attribution and/or deferred deep linking is as follows:
- A user clicks on an ad in their web browser on a mobile device.
- The user is redirected to a special landing page owned by the advertiser. The landing page has a button to download the app and implements the Singular Website SDK.
- When the user clicks "Download", a code that can be used for attribution as well as deferred deep linking is copied into the device's clipboard. The user is redirected to the app store to download the app.
- When the app is opened, the Singular SDK reads the data from the clipboard and can use it to perform deterministic attribution. In addition, the Singular SDK fetches the DDL information and presents the appropriate page or user experience to the user.
What are the advantages of Clipboard-Based DDL?
This is a deterministic method of attribution that does not rely on probabilistic methods such as collecting the user's IP address. This makes it both reliable for the advertiser and compliant with Apple's guidelines on guarding the end-user's privacy.
What are the limits of Clipboard-Based DDL?
- Clipboard-Based DDL works for Apple App Store apps as well as Google Play Store apps (where Singular can take advantage of Google's Play Referrer technology). It is not supported for apps offered as APKs outside of the Play Store.
- The website code can only be run in response to a user input event, which is why the "Download" button in the landing page is necessary.
- If the user copies something else into the clipboard between clicking the "Download" button and opening the app for the first time, this solution will not work.
- When the user opens the app for the first time, if the Singular SDK identifies that there is DDL information available in the clipboard and reads it, the user will see a notification saying that the clipboard has been read ("<App Name> has pasted from Safari").
How do I set up Clipboard-Based DDL for my ads?
1 |
Integrate the Singular Web SDK in your landing page.
For details, see Singular Website SDK: Native Integration.
|
2 |
Add code for web-to-app attribution with the Clipboard-Based DDL flow.
See Website-to-App Attribution Forwarding for Mobile Web for general information about Singular's solution.
To implement Clipboard-Based DDL, use one of the following functions:
This function redirects to the App Store using a Singular Link, with or without additional parameters (such as a deep link), while also encoding the link information and copying it to the device's clipboard.
// Open the app with a base link
singularSdk.openAppWithClipboardDdl ( "https://mydomain.sng.link/Buour/55cx");
// Open the app witha base link + deeplink (‘_dl’) + // passthrough (‘_p’) + deferred deeplink (‘_ddl’) params
singularSdk.openAppWithClipboardDdl ( "https://mydomain.sng.link/Auour/55ba",
"deeplink_value", "passthrough_value", "deferred_value" );
Use this function if you only want to build the link and enrich it with the clipboard flow. You can then use the link later as you prefer.
// Build web-to-app link with no deep link/passthrough/DDL params,
// and enrich it with the clipboard flow
const webToAppLink = singularSdk.enrichUrlWithClipboardDdlFlow (
singularSdk.buildWebToAppLink("https://mydomain.sng.link/Buour/55cx")
);
// Build web-to-app link with deep link ('_dl'), passthrough ('_p'),
// and deferred deep link ('_ddl') params + enrich it with clipboard flow
const webToAppLink = singularSdk.enrichUrlWithClipboardDdlFlow (
singularSdk.buildWebToAppLink(
"https://mydomain.sng.link/Auour/55ba",
"deeplink_value",
"passthrough_value",
"deferred_value"
)
);
Notes:
- Whichever function you use, remember that the clipboard flow can only be triggered by a user action, such as clicking a "Download" button.
- To comply with user privacy guidelines, your landing page should make it clear to the user that the page will be using the device's clipboard feature when the user clicks the "Download" button.
|
3 |
In your app, upgrade to the latest version of the Singular SDK.
|
4 |
Add code to your app to read the deep link information.
Note: This step is only necessary for iOS apps.
The app should read the device clipboard when Singular is initialized. Depending on the SDK you use, the code is as follows:
Full iOS SDK documentation
SingularConfig* config = [[SingularConfig alloc] initWithApiKey:@"<API_KEY>" andSecret:@"<SECRET>"];
config.singularLinksHandler = ^(SingularLinkParams * params) {
[self processDeeplink:params];
};
config.launchOptions = launchOptions;
config.skAdNetworkEnabled = YES;
config.clipboardAttribution = YES;
config.singularLinksHandler = ^(SingularLinkParams *params) {
[self processDeeplink:params];
};
config.espDomains = @[@"singulartest1.sng.link"];
[Singular start:config];
Full React Native SDK documentation
const config = new SingularConfig('<API_KEY>', '<SECRET>');
config.withClipboardAttribution();
// Add any other optional settings
Singular.init(config);
Full Unreal Engine SDK documentation
Change the Initialize method from:
static bool Initialize(FString apiKey, FString apiSecret,
int sessionTimeout = 60,
FString customUserId = TEXT(""),
bool skAdNetworkEnabled = false,
bool manualSkanConversionManagement = false,
int waitForTrackingAuthorizationWithTimeoutInterval = 0,
bool oaidCollection = false);
To:
static bool Initialize(FString apiKey, FString apiSecret,
int sessionTimeout = 60,
FString customUserId = TEXT(""),
bool skAdNetworkEnabled = false,
bool manualSkanConversionManagement = false,
int waitForTrackingAuthorizationWithTimeoutInterval = 0,
bool oaidCollection = false,
bool enableLogging = false,
int logLevel = 3,
bool clipboardAttribution = false);
Full Flutter SDK documentation
SingularConfig config =
SingularConfig('API_KEY', 'API_SECRET');
config.waitForTrackingAuthorizationWithTimeoutInterval = 60;
config.skAdNetworkEnabled = true;
config.clipboardAttribution = true;
config.singularLinksHandler = (SingularLinkParams params) {
print('Received deferred deeplink: ');
deeplinkParams['deeplink'] = params.deeplink;
deeplinkParams['passthrough'] = params.passthrough;
deeplinkParams['isDeferred'] = params.isDeferred;
};
config.conversionValueUpdatedCallback = (int conversionValue) {
print('Received conversionValueUpdatedCallback: ' +
conversionValue.toString());
};
Singular.start(config);
|