Developer Documentation
Integrate Blaink SDK into your iOS, Android, and React Native applications with our comprehensive guides and code examples.
iOS Integration
Get started with Blaink SDK for iOS in just a few simple steps. Our SDK is designed to be lightweight and easy to integrate.
Installation via Swift Package Manager
Add the Blaink SDK to your Xcode project using Swift Package Manager:
dependencies: [
.package(url: "https://git.blainks.com/blainks/blainks-ios.git", from: "1.5.4")
]
Via Xcode UI
- Go to File > Add Package Dependencies
- Enter the repository URL:
https://git.blainks.com/blainks/blainks-ios.git - Select the version and click Add Package
Enable Push Notifications Capability
Configure your Xcode project to receive push notifications:
Choose Registration Method
The SDK supports two methods for handling device token registration and deeplinks. Choose the one that best fits your needs:
Automatic Registration
Uses method swizzling to automatically intercept the device token from APNs and handle deeplinks. This is the simplest integration method with minimal code required.
import Blainks
import SwiftUI
class AppDelegate: NSObject, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
// Enable automatic device token registration (uses method swizzling)
Blaink.enableAutoTokenRegistration()
// Enable automatic deeplink handling (uses method swizzling)
Blaink.enableAutoDeeplinkHandling()
// Setup Blaink SDK
Blaink.shared.setup(
sdkKey: "YOUR_SDK_KEY",
environment: .production, // or .development for sandbox
isDebugLogsEnabled: false
)
Blaink.shared.delegate = self
// Register for remote notifications (requests permission + registers with APNs)
Blaink.shared.registerForRemoteNotifications()
return true
}
}
extension AppDelegate: BlainkDelegate {
func didReceiveNotification(_ notification: [AnyHashable: Any]) {
// Handle notification tap
print("User tapped notification: \(notification)")
}
func didRegisterForBlainkNotifications(blainkUserId: String) {
// SDK successfully registered with Blaink servers
print("Registered with Blaink, user ID: \(blainkUserId)")
}
}
import UIKit
import Blainks
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// Enable automatic device token registration (uses method swizzling)
Blaink.enableAutoTokenRegistration()
// Enable automatic deeplink handling (uses method swizzling)
Blaink.enableAutoDeeplinkHandling()
// Setup Blaink SDK
Blaink.shared.setup(
sdkKey: "YOUR_SDK_KEY",
environment: .production,
isDebugLogsEnabled: false
)
Blaink.shared.delegate = self
// Register for remote notifications (requests permission + registers with APNs)
Blaink.shared.registerForRemoteNotifications()
return true
}
}
extension AppDelegate: BlainkDelegate {
func didReceiveNotification(_ notification: [AnyHashable: Any]) {
// Handle notification tap
print("User tapped notification: \(notification)")
}
func didRegisterForBlainkNotifications(blainkUserId: String) {
// SDK successfully registered with Blaink servers
print("Registered with Blaink, user ID: \(blainkUserId)")
}
}
Manual Registration
Gives you full control over device token handling and deeplinks. Use this if method swizzling conflicts with other SDKs in your project or if you prefer explicit control.
import Blainks
import SwiftUI
class AppDelegate: NSObject, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
) -> Bool {
// Do NOT call Blaink.enableAutoTokenRegistration()
// Do NOT call Blaink.enableAutoDeeplinkHandling()
// Setup Blaink SDK
Blaink.shared.setup(
sdkKey: "YOUR_SDK_KEY",
environment: .production,
isDebugLogsEnabled: false
)
Blaink.shared.delegate = self
// Register for remote notifications
Blaink.shared.registerForRemoteNotifications()
return true
}
// Manually forward the device token to Blaink
func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
Blaink.shared.registerForRemoteNotificationsWithDeviceToken(deviceToken)
}
// Optional: Handle registration failure
func application(
_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error
) {
print("Failed to register for remote notifications: \(error)")
}
}
extension AppDelegate: BlainkDelegate {
func didReceiveNotification(_ notification: [AnyHashable: Any]) {
print("User tapped notification: \(notification)")
}
func didRegisterForBlainkNotifications(blainkUserId: String) {
print("Registered with Blaink, user ID: \(blainkUserId)")
}
}
Manual Deeplink Handling Required
When using manual registration, you must also handle deeplinks manually in your YourApp.swift file. See the URL Scheme Setup section below for the complete code.
import UIKit
import Blainks
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// Do NOT call Blaink.enableAutoTokenRegistration()
// Do NOT call Blaink.enableAutoDeeplinkHandling()
// Setup Blaink SDK
Blaink.shared.setup(
sdkKey: "YOUR_SDK_KEY",
environment: .production,
isDebugLogsEnabled: false
)
Blaink.shared.delegate = self
// Register for remote notifications
Blaink.shared.registerForRemoteNotifications()
return true
}
// Manually forward the device token to Blaink
func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
Blaink.shared.registerForRemoteNotificationsWithDeviceToken(deviceToken)
}
// Optional: Handle registration failure
func application(
_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error
) {
print("Failed to register for remote notifications: \(error)")
}
// Manually handle deeplinks
func application(
_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
return Blaink.shared.handleDeeplink(url)
}
}
extension AppDelegate: BlainkDelegate {
func didReceiveNotification(_ notification: [AnyHashable: Any]) {
print("User tapped notification: \(notification)")
}
func didRegisterForBlainkNotifications(blainkUserId: String) {
print("Registered with Blaink, user ID: \(blainkUserId)")
}
}
URL Scheme Setup (for Deeplinks)
To handle deeplinks from notifications, add a URL scheme to your app:
YOUR_DEEPLINK_SCHEME
Replace Deeplink Scheme
Replace YOUR_DEEPLINK_SCHEME with your app's deeplink scheme (provided by Blaink). You can use the platform selector above to auto-fill your credentials.
Manual Registration Only: SwiftUI Deeplink Handling
If you chose Manual Registration with SwiftUI, you need to handle deeplinks in your app entry point:
import Blainks
import SwiftUI
@main
struct YourApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
.onOpenURL { url in
// Manually handle deeplinks
_ = Blaink.shared.handleDeeplink(url)
}
}
}
}
Automatic Registration
If you're using Automatic Registration with Blaink.enableAutoDeeplinkHandling(), deeplinks are handled automatically and you don't need the .onOpenURL modifier.
Add Notification Service Extension Optional but Recommended
For tracking notification delivery, add a Notification Service Extension:
NotificationService)
import UserNotifications
import Blainks
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(
_ request: UNNotificationRequest,
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
) {
self.contentHandler = contentHandler
bestAttemptContent = request.content.mutableCopy() as? UNMutableNotificationContent
// Track delivery with Blainks
Task {
await Blaink.shared.didReceive(request)
}
// Deliver the notification
if let bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
override func serviceExtensionTimeWillExpire() {
// Called just before the extension will be terminated by the system.
if let contentHandler, let bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
}
API Reference
Blaink
| Method | Description |
|---|---|
Blaink.shared |
Shared singleton instance |
Blaink.enableAutoTokenRegistration() |
Enables automatic device token forwarding via method swizzling. Call this before setup() if using automatic registration. |
Blaink.enableAutoDeeplinkHandling() |
Enables automatic deeplink handling via method swizzling. Swizzles both application(_:open:options:) for UIKit apps and scene(_:openURLContexts:) for SwiftUI/Scene-based apps (iOS 13+). Call this before setup() if using automatic handling. |
setup(sdkKey:environment:isDebugLogsEnabled:) |
Initialize the SDK with your API key |
registerForRemoteNotifications() |
Request notification permission and register with APNs |
registerForRemoteNotificationsWithDeviceToken(_:) |
Manually register device token with Blaink (use this if not using auto registration) |
handleDeeplink(_:) |
Manually handle deeplinks from notifications (use this if not using auto handling) |
didReceive(_:) async |
Called from Notification Service Extension to track delivery. This is an async method - use Task { await Blaink.shared.didReceive(request) } |
BlainkDelegate
| Method | Description |
|---|---|
didReceiveNotification(_:) |
Called when user taps a notification |
didRegisterForBlainkNotifications(blainkUserId:) |
Called when SDK successfully registers with Blaink servers |
PushEnvironment
| Value | Description |
|---|---|
.production |
Use APNs production environment |
.development |
Use APNs sandbox environment |
Android Integration
Get started with Blaink SDK for Android. Features include FCM integration, automatic deeplink handling, SSL pinning, and secure storage.
Installation
Add the Blaink SDK to your project:
First, add our Maven repository to your settings.gradle.kts:
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url = uri("https://blainks.com/maven") }
}
}
Then add the dependency to your app's build.gradle.kts:
dependencies {
implementation("com.blainks:blaink:1.5.4")
}
Add Firebase to Your Project
Follow the Firebase Android setup guide to add Firebase to your project:
google-services.json to your app module
build.gradle.kts
plugins {
id("com.google.gms.google-services")
}
Update AndroidManifest.xml
Add the Blaink FCM service and deeplink intent filter:
<application ...>
<!-- Blaink FCM Service -->
<service
android:name="com.blaink.push.BlainkFCMService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<!-- Blaink Notification Dismiss Receiver (for tracking dismissed notifications) -->
<receiver
android:name="com.blaink.push.NotificationDismissReceiver"
android:exported="false">
<intent-filter>
<action android:name="BLAINK_NOTIFICATION_DISMISS" />
</intent-filter>
</receiver>
<!-- Add deeplink support to your launcher activity -->
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- Blaink Deeplink Handler -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="YOUR_DEEPLINK_SCHEME" />
</intent-filter>
</activity>
</application>
Replace Deeplink Scheme
Replace YOUR_DEEPLINK_SCHEME with your app's deeplink scheme (provided by Blaink). You can use the platform selector above to auto-fill your credentials.
Initialize the SDK
Create or update your Application class:
class MyApplication : Application(), BlainkDelegate {
override fun onCreate() {
super.onCreate()
Blaink.getInstance().apply {
delegate = this@MyApplication
setup(
context = this@MyApplication,
sdkKey = "YOUR_SDK_KEY",
environment = PushEnvironment.PRODUCTION,
isDebugLogsEnabled = BuildConfig.DEBUG
)
}
}
override fun didReceiveNotification(notification: Map<String, Any>) {
// Called when a push notification is received
Log.d("Blaink", "Notification received: $notification")
}
override fun didRegisterForBlainkNotifications(blainkUserId: String) {
// Called when device is successfully registered with Blaink
Log.d("Blaink", "Registered with user ID: $blainkUserId")
}
}
Replace SDK Key
Replace YOUR_SDK_KEY with your platform's SDK key (provided by Blaink). You can use the platform selector above to auto-fill your credentials.
Register your Application class in AndroidManifest.xml:
<application
android:name=".MyApplication"
...>
Register for Push Notifications
In your main activity, call registerForRemoteNotifications():
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Register for push notifications
// This automatically:
// - Requests POST_NOTIFICATIONS permission on Android 13+
// - Fetches the FCM token
// - Registers with Blaink backend
Blaink.getInstance().registerForRemoteNotifications(this)
}
}
That's it!
The SDK automatically handles:
- FCM token retrieval and registration
- Notification permission requests (Android 13+)
- Deeplink handling via
ActivityLifecycleCallbacks
Advanced Usage
Manual FCM Token Registration
If you manage FCM tokens yourself:
FirebaseMessaging.getInstance().token.addOnSuccessListener { token ->
Blaink.getInstance().registerFCMToken(token)
}
Manual Deeplink Handling
The SDK automatically handles deeplinks, but you can also handle them manually:
// Returns true if the deeplink was handled by Blaink
val handled = Blaink.getInstance().handleDeeplink(uri.toString())
Session Management
// Check if user is authenticated
if (UserSession.isAuthenticated) {
// User is logged in
}
// Get current user
lifecycleScope.launch {
val result = Blaink.getInstance().getCurrentUser()
result.onSuccess { userId ->
Log.d("Blaink", "User ID: $userId")
}
}
// Logout
lifecycleScope.launch {
val result = Blaink.getInstance().logout()
result.onSuccess {
Log.d("Blaink", "Logged out successfully")
}
}
ProGuard / R8 Configuration
Add these rules to your proguard-rules.pro:
# Blaink SDK
-keep class com.blaink.** { *; }
-dontwarn com.blaink.**
# Kotlinx Serialization
-keepattributes *Annotation*, InnerClasses
-dontnote kotlinx.serialization.AnnotationsKt
API Reference
Blaink
| Method | Description |
|---|---|
Blaink.getInstance() |
Get the singleton instance |
setup(context, sdkKey, environment, isDebugLogsEnabled) |
Initialize the SDK with your configuration |
registerForRemoteNotifications(activity) |
Request permission, fetch FCM token, and register with Blaink (recommended) |
registerFCMToken(token) |
Manually register an FCM token with Blaink |
handleDeeplink(url) |
Manually handle a deeplink URL. Returns true if handled. |
getCurrentUser() |
Get the current user ID (suspend function) |
logout() |
Logout and unregister from push notifications (suspend function) |
trackNotificationAction(notificationId, action) |
Track notification interactions (opened, dismissed) |
BlainkDelegate
| Method | Description |
|---|---|
didReceiveNotification(notification) |
Called when a push notification is received (delivered) |
didRegisterForBlainkNotifications(blainkUserId) |
Called when device is successfully registered with Blaink |
PushEnvironment
| Value | Description |
|---|---|
PushEnvironment.PRODUCTION |
Use for production/release builds |
PushEnvironment.DEVELOPMENT |
Use for debug/development builds |
React Native Integration
Get started with Blaink SDK for React Native. The react-native-blaink package is a thin bridge that wraps the native iOS and Android SDKs — zero business logic lives in the JavaScript layer.
Installation
Install the package from npm:
npm install react-native-blaink
iOS — Swift Package Manager
The iOS native SDK is added automatically via SPM when you run pod install. No CocoaPods dependency is required for the Blaink SDK itself.
Android — Maven Repository
Add the Blaink Maven repository to your project-level build.gradle or settings.gradle.kts:
allprojects {
repositories {
maven { url "https://blainks.com/maven" }
}
}
Platform Setup
iOS
Android
google-services.json to android/app/
build.gradle
Add the Blaink FCM service and deeplink intent filter to your AndroidManifest.xml:
<application ...>
<!-- Blaink FCM Service -->
<service
android:name="com.blaink.push.BlainkFCMService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<!-- Blaink Notification Dismiss Receiver -->
<receiver
android:name="com.blaink.push.NotificationDismissReceiver"
android:exported="false">
<intent-filter>
<action android:name="BLAINK_NOTIFICATION_DISMISS" />
</intent-filter>
</receiver>
<!-- Add deeplink support to your main activity -->
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTask">
<!-- Blaink Deeplink Handler -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="YOUR_DEEPLINK_SCHEME" />
</intent-filter>
</activity>
</application>
Also add the deeplink scheme to your iOS Info.plist:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>YOUR_DEEPLINK_SCHEME</string>
</array>
</dict>
</array>
Replace Credentials
Replace YOUR_DEEPLINK_SCHEME with the deeplink scheme provided by Blaink for each platform. You can use the platform selector above to auto-fill your credentials.
Initialize the SDK
Initialize Blaink in your app's entry point. Call setup() once, and register event listeners to receive notifications and registration callbacks:
import { useEffect } from 'react';
import { Platform } from 'react-native';
import {
Blaink,
PushEnvironment,
addNotificationListener,
addRegistrationListener,
} from 'react-native-blaink';
const SDK_KEY = Platform.select({
ios: 'YOUR_IOS_SDK_KEY',
android: 'YOUR_ANDROID_SDK_KEY',
})!;
export default function App() {
useEffect(() => {
// Initialize the SDK
Blaink.setup({
sdkKey: SDK_KEY,
environment: PushEnvironment.PRODUCTION,
debugLogsEnabled: __DEV__,
});
// Listen for push notifications
const notifSub = addNotificationListener((payload) => {
console.log('Notification:', payload);
});
// Listen for Blaink registration
const regSub = addRegistrationListener((blainkUserId) => {
console.log('Registered:', blainkUserId);
});
return () => {
notifSub.remove();
regSub.remove();
};
}, []);
// ...
}
Replace SDK Keys
Replace YOUR_IOS_SDK_KEY and YOUR_ANDROID_SDK_KEY with your platform SDK keys (provided by Blaink). You can use the platform selector above to auto-fill your credentials.
Register for Push Notifications
Call registerForRemoteNotifications() to request permission and register the device with Blaink:
import { Blaink } from 'react-native-blaink';
async function registerPush() {
try {
await Blaink.registerForRemoteNotifications();
console.log('Push registration requested');
} catch (error) {
console.error('Push registration failed:', error);
}
}
Automatic Handling
This single call handles everything per platform:
- iOS: Requests notification permission and registers the APNs token
- Android: Requests
POST_NOTIFICATIONSpermission (Android 13+), fetches the FCM token, and registers with Blaink
Handle Deeplinks
Handle incoming deeplink URLs via the SDK:
import { Blaink } from 'react-native-blaink';
import { Linking } from 'react-native';
// Listen for deeplinks from React Native's Linking API
Linking.addEventListener('url', async ({ url }) => {
const handled = await Blaink.handleDeeplink(url);
if (!handled) {
// Handle non-Blaink deeplinks yourself
}
});
Add Notification Service Extension (iOS) Optional but Recommended
To track notification delivery (read/dismiss states), add a Notification Service Extension to your iOS project. This is a separate target that runs outside your React Native app — it intercepts notifications before they are displayed.
NotificationService)
Podfile (see below)
Add the extension target to your Podfile:
# Add after your main app target block
target 'NotificationService' do
pod 'BlainkNotificationService', :path => '.'
end
Create a local podspec that wraps the Blainks SPM dependency for the extension:
require Pod::Executable.execute_command('node', ['-p',
'require.resolve("react-native/scripts/react_native_pods.rb", {paths: [process.argv[1]]})',
__dir__ + '/..'
]).strip
Pod::Spec.new do |s|
s.name = "BlainkNotificationService"
s.version = "1.0.0"
s.summary = "Blainks SDK for Notification Service Extension"
s.homepage = "https://blainks.com"
s.license = "MIT"
s.authors = "Blaink"
s.platforms = { :ios => "13.0" }
s.source = { :git => "" }
s.source_files = "NotificationService/**/*.swift"
spm_dependency(s,
url: 'https://git.blainks.com/blainks/blainks-ios.git',
requirement: { kind: 'upToNextMajorVersion', minimumVersion: '1.5.4' },
products: ['Blainks']
)
end
Then run cd ios && pod install to link the dependency.
Why a local podspec?
The main app gets the Blainks SDK through CocoaPods via spm_dependency in the library podspec. Extension targets need the same mechanism — a local podspec that uses spm_dependency to resolve the SPM package for the extension.
import UserNotifications
import Blainks
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(
_ request: UNNotificationRequest,
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void
) {
self.contentHandler = contentHandler
bestAttemptContent = request.content.mutableCopy() as? UNMutableNotificationContent
// Track delivery with Blainks
Task {
await Blaink.shared.didReceive(request)
}
// Deliver the notification
if let bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
override func serviceExtensionTimeWillExpire() {
if let contentHandler, let bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
}
Blaink.shared.didReceive(request) which reports delivery back to the server, enabling read/dismiss analytics in your dashboard.
This is pure native code
The Notification Service Extension runs in a separate process outside of React Native. It imports Blainks directly — no bridge code is needed. The extension's bundle identifier should be your.app.bundle.id.NotificationService.
Analytics
Track events, screens, and user properties with the built-in analytics module:
import { analytics } from 'react-native-blaink';
// Track a custom event
analytics.log('purchase_completed', {
productId: '12345',
amount: 29.99,
});
// Track screen view
analytics.setScreen('ProductDetail', 'App');
// Set user properties
analytics.setUserProperty('premium', 'true');
analytics.setUser({ tier: 'premium', region: 'eu' });
// Flush pending events
analytics.flush();
Localisation
Server-synced translations with local fallback:
import { localisation } from 'react-native-blaink';
// Sync translations from the backend
const updatedKeys = await localisation.sync();
// Get a translated string
const title = await localisation.getString('welcome_title');
// Get translation for a specific language
const titleDE = await localisation.getString('welcome_title', 'de');
// Get current language
const lang = await localisation.getLanguage();
// Set active language
localisation.setLanguage('fr');
// Get all available languages
const languages = await localisation.getAvailableLanguages();
API Reference
Blaink
| Method | Description |
|---|---|
Blaink.setup(config) |
Initialize the SDK with sdkKey, environment, and debugLogsEnabled |
Blaink.registerForRemoteNotifications() |
Request push permission and register device with Blaink. Returns Promise<void> |
Blaink.registerDeviceToken(token) |
Manually register a device token (APNs/FCM) |
Blaink.handleDeeplink(url) |
Handle a deeplink URL. Returns Promise<boolean> |
Event Listeners
| Function | Description |
|---|---|
addNotificationListener(callback) |
Fires when a push notification is received |
addRegistrationListener(callback) |
Fires when the device is registered with Blaink (returns blainkUserId) |
addDeferredDeeplinkResolvedListener(callback) |
Fires when a deferred deeplink is resolved on first install |
addDeferredDeeplinkFailedListener(callback) |
Fires when deferred deeplink resolution fails |
analytics
| Method | Description |
|---|---|
analytics.log(name, params?) |
Track a custom event with optional parameters |
analytics.setScreen(name, screenClass?, properties?) |
Track a screen view with optional class and properties |
analytics.setUserProperty(name, value) |
Set a single user property |
analytics.setUser(properties) |
Set multiple user properties at once |
analytics.flush() |
Flush pending analytics events |
localisation
| Method | Description |
|---|---|
localisation.sync() |
Sync translations from server. Returns Promise<number | null> |
localisation.getString(key, lang?) |
Get translated string by key. Returns Promise<string> |
localisation.getOptionalString(key) |
Get translated string or null. Returns Promise<string | null> |
localisation.getLanguage() |
Get current language code. Returns Promise<string> |
localisation.setLanguage(lang) |
Set the active language |
localisation.getAvailableLanguages() |
Get list of available languages. Returns Promise<string[]> |
localisation.getAllTranslations(key) |
Get all translations for a key. Returns Promise<Record<string, string>> |
localisation.getCachedVersion() |
Get cached translation version. Returns Promise<number> |
localisation.clearCache() |
Clear local translation cache |
PushEnvironment
| Value | Description |
|---|---|
PushEnvironment.PRODUCTION |
Use for production/release builds |
PushEnvironment.DEVELOPMENT |
Use for debug/development builds |
Web Integration
Implement push notifications for your Web Application using Firebase Cloud Messaging (FCM). Supports Chrome, Firefox, Edge, and Safari (iOS 16.4+).
Simple Integration
If your domain is registered in the Blaink Admin Panel, the SDK auto-configures itself. Just add the SDK, create a one-line service worker file, and call Blaink.init()!
Add Blaink SDK
Add the Blaink Web SDK to your HTML file (e.g., index.html):
<!-- Blaink Web SDK -->
<script src="https://blainks.com/blaink.js"></script>
Service Worker Auto-Generated
No Setup Required
When you configure Push Notifications for your Web platform in the Admin Panel, Blaink automatically serves /firebase-messaging-sw.js for your domain with your Firebase configuration pre-loaded. No files to create!
Initialize & Register
Initialize the SDK and request notification permission from the user.
User Interaction Required
Browsers require notification permission to be requested from a user gesture (like a button click). You cannot request permission automatically on page load.
Add a button with the special ID blaink-notification-button. The SDK will automatically attach click handlers:
<!-- SDK auto-attaches click handler to this button -->
<button id="blaink-notification-button">Enable Notifications</button>
Then initialize the SDK at the end of your HTML body (after the button element):
<script>Blaink.init();</script>
Custom Button Handling
If you prefer to use your own button or trigger, you can manually call Blaink.requestPermission() from any user gesture:
// Custom button click handler
document.getElementById('my-button').addEventListener('click', async () => {
const token = await Blaink.requestPermission();
if (token) {
console.log('Notifications enabled!', token);
// Optional: Link device to your authenticated user
const deviceId = localStorage.getItem('blaink_device_id');
if (deviceId) {
await fetch('/your-api/link-device', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + userAccessToken
},
body: JSON.stringify({ deviceId: deviceId })
});
}
}
});
PWA Configuration Optional
For the best experience on iOS Safari, configure your app as a Progressive Web App (PWA). This enables reliable push notifications when users add your site to their home screen.
Auto-Generated PWA Files
If you configure PWA settings in the Blaink Admin Panel when creating your Web platform, Blaink will automatically generate and serve your manifest.json and firebase-messaging-sw.js files. Just link to them in your HTML - no need to create these files manually!
Add these meta tags to your HTML <head> section:
<!-- PWA Configuration -->
<!-- If using Blaink auto-generated files: -->
<link rel="manifest" href="/manifest.json">
<!-- Apple Touch Icon (use your own icon) -->
<link rel="icon" type="image/png" href="/images/app_icon.png">
<link rel="apple-touch-icon" href="/images/app_icon.png">
<meta name="theme-color" content="#0f172a">
Option A: Use Blaink Auto-Generated Files (Recommended)
When you create a Web platform in the Admin Panel with PWA configuration enabled, Blaink automatically serves:
/manifest.json- Generated from your PWA settings (app name, colors, icons, etc.)/firebase-messaging-sw.js- Pre-configured service worker with your Firebase settings
No additional files needed - just link to them as shown above!
Option B: Manual Configuration
If you prefer to create your own files, create a manifest.json file in your website's root directory:
{
"name": "Your App Name",
"short_name": "App",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#0f172a",
"icons": [
{
"src": "/images/app_icon.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/images/app_icon.png",
"sizes": "512x512",
"type": "image/png"
}
]
}
iOS Add to Home Screen
On iOS Safari, guide users to tap the Share button and select Add to Home Screen. This creates a standalone app experience with full push notification support.
Important Requirements
HTTPS Required
Web Push requires a Secure Context (HTTPS). It will not work on HTTP (except for localhost).
Safari Support
Supported on macOS (Safari 16+) and iOS (16.4+). For iOS, users must Add to Home Screen for the most reliable experience.
API Reference
Blaink SDK Methods
| Method | Description |
|---|---|
Blaink.init([sdkKey]) |
Initialize the SDK. If sdkKey is omitted, auto-configures based on the current domain (domain must be registered in Admin Panel). Loads Firebase and registers the service worker. |
Blaink.requestPermission() |
Request notification permission from the user. Returns a Promise that resolves with the FCM token if granted. |
Blaink.onMessage(callback) |
Register a callback for foreground messages. The callback receives the FCM payload object. |
LocalStorage Keys
| Key | Description |
|---|---|
blaink_client_id |
Unique client identifier (UUID) persisted across sessions. |
blaink_device_id |
Unique device identifier (UUID) used to link push tokens to authenticated users. |
Service Worker Messages
| Message Type | Description |
|---|---|
NOTIFICATION_CLICK |
Sent from service worker when user clicks a notification. Contains url property for navigation. |
Deferred Deep Links — iOS
Deferred deep links allow users who click a link but don't have the app installed to land on the intended content after installing from the App Store.
How It Works
The flow is simple:
- User clicks a deferred link (e.g.
https://yourapp.blainks.com/d/abc123) - A redirect page collects device fingerprint signals and redirects to the App Store
- User installs and opens the app
- The SDK sends the device fingerprint to the backend for matching
- Your delegate receives the original destination URL
- iOS < 16: Token via clipboard (deterministic, silent)
- iOS 16+: Fingerprint matching (probabilistic) or App Clips (deterministic)
Backend Setup
Enable deferred deep links for your project in the admin dashboard:
- Go to Admin → Deferred Links
- Enter your desired subdomain slug (e.g.
myapp→myapp.blainks.com) - Go to Settings and enter your Apple Team ID for the iOS platform
- Save — the subdomain, nginx config, SSL certificate, and AASA file will be created automatically
SDK Integration
Set the deferred deeplink delegate before calling setup():
import Blainks
class AppDelegate: UIResponder, UIApplicationDelegate,
BlainksDeferredDeeplinkDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions options: ...) -> Bool {
// Set deferred deeplink delegate BEFORE setup
Blaink.shared.deferredDeeplinkDelegate = self
Blaink.shared.setup(sdkKey: "YOUR_SDK_KEY")
return true
}
// MARK: - BlainksDeferredDeeplinkDelegate
func didResolveDeferredDeeplink(destination: String,
metadata: [String: String]?) {
// Navigate to the destination screen
print("Deferred link: \(destination)")
}
func deferredDeeplinkResolutionFailed(
error: BlainksDeferredDeeplinkError
) {
// Optional: log or handle failures
}
}
App Clips (Optional, iOS 16+)
For deterministic matching on iOS 16+ (where clipboard is not available), you can use an App Clip to pass the token through a shared App Group container.
Setup:
- Create an App Clip target in Xcode (File → New → Target → App Clip)
- Add a shared App Group to both the App Clip and main app (e.g.
group.com.yourapp.shared) - Configure the App Group ID before
setup()
// Set App Group before setup
AppClipSupport.appGroupID = "group.com.yourapp.shared"
Blaink.shared.deferredDeeplinkDelegate = self
Blaink.shared.setup(sdkKey: "YOUR_SDK_KEY")
import SwiftUI
import Blainks
@main
struct SampleAppClipApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.onContinueUserActivity(
NSUserActivityTypeBrowsingWeb
) { activity in
handleIncomingURL(activity)
}
}
}
private func handleIncomingURL(_ activity: NSUserActivity) {
guard let url = activity.webpageURL else { return }
let path = url.pathComponents
if let dIdx = path.firstIndex(of: "d"),
dIdx + 1 < path.count {
let token = path[dIdx + 1]
AppClipSupport.appGroupID = "group.com.yourapp.shared"
AppClipSupport.storeTokenFromAppClip(token)
}
}
}
Creating Deferred Links (API)
Create deferred links programmatically via the API:
curl -X POST https://blainks.com/api/v1/deferred-links \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"destination": "product/12345",
"metadata": {"campaign": "summer_sale"},
"expiresInHours": 48
}'
Response:
{
"token": "a1B2c3D4",
"url": "https://yourapp.blainks.com/d/a1B2c3D4",
"expiresAt": "2026-02-23T12:00:00Z"
}
Error Handling
| Error | Description |
|---|---|
noMatchFound |
No click record matched this device's fingerprint |
alreadyChecked |
The check already ran on this install. Resets on reinstall. |
networkError |
Network request failed |
sdkNotInitialized |
setup() has not been called yet |
Deferred Deep Links — Android
Deferred deep links allow users who click a link but don't have the app installed to land on the intended content after installing from the Play Store.
How It Works
The flow is simple:
- User clicks a deferred link (e.g.
https://yourapp.blainks.com/d/abc123) - A redirect page collects device fingerprint signals and redirects to the Play Store
- User installs and opens the app
- The SDK uses Play Install Referrer (deterministic) with fingerprint fallback
- Your listener receives the original destination URL
Backend Setup
Enable deferred deep links for your project in the admin dashboard:
- Go to Admin → Deferred Links
- Enter your desired subdomain slug (e.g.
myapp→myapp.blainks.com) - Go to Settings and enter your SHA-256 certificate fingerprints for the Android platform
- Save — the subdomain, nginx config, SSL certificate, and assetlinks.json will be created automatically
SDK Integration
Set the deferred deeplink listener before calling setup():
import com.blaink.Blaink
import com.blaink.core.deferredlink.BlainkDeferredDeeplinkListener
import com.blaink.core.deferredlink.BlainkDeferredDeeplinkError
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
val blaink = Blaink.getInstance()
blaink.deferredDeeplinkListener =
object : BlainkDeferredDeeplinkListener {
override fun onDeferredDeeplinkResolved(
destination: String,
metadata: Map<String, String>?
) {
Log.d("Blaink", "Deferred link: $destination")
}
override fun onDeferredDeeplinkFailed(
error: BlainkDeferredDeeplinkError
) {
// Optional: handle failures
}
}
blaink.setup(
context = this,
sdkKey = "YOUR_SDK_KEY"
)
}
}
intent-filter with android:autoVerify="true" for your subdomain. Add your SHA-256 fingerprint in the platform settings — the backend serves assetlinks.json automatically.
Creating Deferred Links (API)
Create deferred links programmatically via the API:
curl -X POST https://blainks.com/api/v1/deferred-links \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"destination": "product/12345",
"metadata": {"campaign": "summer_sale"},
"expiresInHours": 48
}'
Response:
{
"token": "a1B2c3D4",
"url": "https://yourapp.blainks.com/d/a1B2c3D4",
"expiresAt": "2026-02-23T12:00:00Z"
}
Error Handling
| Error | Description |
|---|---|
noMatchFound |
No click record matched this device's fingerprint |
alreadyChecked |
The check already ran on this install. Resets on reinstall. |
networkError |
Network request failed |
sdkNotInitialized |
setup() has not been called yet |
Deferred Deep Links — React Native
Deferred deep links allow users who click a link but don't have the app installed to land on the intended content after installing from the App Store or Play Store.
How It Works
The flow is simple:
- User clicks a deferred link (e.g.
https://yourapp.blainks.com/d/abc123) - A redirect page collects device fingerprint signals and redirects to the App Store / Play Store
- User installs and opens the app
- The native SDK detects the deferred link and resolves it
- Your JavaScript listener receives the original destination URL
- iOS < 16: Token via clipboard (deterministic, silent)
- iOS 16+: Fingerprint matching (probabilistic) or App Clips (deterministic)
- Android: Play Install Referrer (deterministic) with fingerprint fallback
Backend Setup
Enable deferred deep links for your project in the admin dashboard:
- Go to Admin → Deferred Links
- Enter your desired subdomain slug (e.g.
myapp→myapp.blainks.com) - Go to Settings and enter your Apple Team ID (iOS) and/or SHA-256 certificate fingerprints (Android)
- Save — the subdomain, nginx config, SSL certificate, AASA file, and assetlinks.json will be created automatically
SDK Integration
Register your deferred deeplink listeners before calling Blaink.setup() so you don't miss the resolution event on first launch:
import { useEffect } from 'react';
import { Platform } from 'react-native';
import {
Blaink,
PushEnvironment,
addDeferredDeeplinkResolvedListener,
addDeferredDeeplinkFailedListener,
} from 'react-native-blaink';
const SDK_KEY = Platform.select({
ios: 'YOUR_IOS_SDK_KEY',
android: 'YOUR_ANDROID_SDK_KEY',
})!;
export default function App() {
useEffect(() => {
// Register deferred deeplink listeners BEFORE setup
const resolvedSub = addDeferredDeeplinkResolvedListener((result) => {
console.log('Deferred link destination:', result.destination);
console.log('Metadata:', result.metadata);
// Navigate to the destination screen
});
const failedSub = addDeferredDeeplinkFailedListener((error) => {
console.log('Deferred link failed:', error);
});
// Initialize the SDK
Blaink.setup({
sdkKey: SDK_KEY,
environment: PushEnvironment.PRODUCTION,
debugLogsEnabled: __DEV__,
});
return () => {
resolvedSub.remove();
failedSub.remove();
};
}, []);
// ...
}
Listener Order Matters
Always register addDeferredDeeplinkResolvedListener and addDeferredDeeplinkFailedListener before calling Blaink.setup(). The SDK checks for deferred deeplinks during initialization, and if your listener isn't registered yet, you'll miss the event.
Creating Deferred Links (API)
Create deferred links programmatically via the API:
curl -X POST https://blainks.com/api/v1/deferred-links \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"destination": "product/12345",
"metadata": {"campaign": "summer_sale"},
"expiresInHours": 48
}'
Response:
{
"token": "a1B2c3D4",
"url": "https://yourapp.blainks.com/d/a1B2c3D4",
"expiresAt": "2026-02-23T12:00:00Z"
}
Event Listener Reference
| Function | Callback Argument | Description |
|---|---|---|
addDeferredDeeplinkResolvedListener |
{ destination: string, metadata?: Record<string, string> } |
Fired when a deferred deeplink is matched on first install |
addDeferredDeeplinkFailedListener |
DeferredDeeplinkError |
Fired when deferred deeplink resolution fails |
Error Handling
The addDeferredDeeplinkFailedListener callback receives one of the following error codes:
| Error | Description |
|---|---|
NO_MATCH_FOUND |
No click record matched this device's fingerprint |
ALREADY_CHECKED |
The check already ran on this install. Resets on reinstall. |
NETWORK_ERROR |
Network request failed |
SDK_NOT_INITIALIZED |
setup() has not been called yet |
import {
addDeferredDeeplinkFailedListener,
DeferredDeeplinkError,
} from 'react-native-blaink';
addDeferredDeeplinkFailedListener((error) => {
switch (error) {
case DeferredDeeplinkError.NO_MATCH_FOUND:
// Normal for organic installs — no action needed
break;
case DeferredDeeplinkError.ALREADY_CHECKED:
// Already resolved on a previous launch
break;
case DeferredDeeplinkError.NETWORK_ERROR:
// Retry or show offline banner
break;
case DeferredDeeplinkError.SDK_NOT_INITIALIZED:
console.error('Blaink.setup() must be called first');
break;
}
});
Need Help?
Our team is here to help you integrate Blaink SDK successfully. Get in touch with us for support and guidance.