Install the Incode Onboarding Cordova Plugin and complete per-platform setup for Android and iOS.
Prerequisites
- Node.js version 18 or later, for the Cordova CLI and your app.
- Cordova CLI version 11 or later. Install with
npm install -g cordova. - Android Studio / SDK: minSdk 23+,
compileSdk36, Android Gradle Plugin 8.9.1, Gradle 8.14.5, Kotlin 2.2.21, JDK 17 to run Gradle. Required for Android builds. - Xcode with iOS 13 or later target. Required for iOS builds (macOS only).
- Incode API credentials: API key and base URL, provided by Incode.
- GitHub personal access token with
read:packagesscope, for Incode's Android Maven repository.
Install the plugin
cordova plugin add https://github.com/Incode-Technologies-Example-Repos/CordovaPluginReleases.git#release/[VERSION]
For the NFC variant (NFC-capable hardware required):
cordova plugin add "https://github.com/Incode-Technologies-Example-Repos/CordovaPluginReleases.git#release/[VERSION]-nfc"
The SDK uses the camera to capture ID and face, so add the camera plugin:
cordova plugin add cordova-plugin-camera
If you use the geolocation module, add the geolocation plugin as well:
cordova plugin add cordova-plugin-geolocation
Then add the platforms you target. Pin the platform versions confirmed compatible with the SDK rather than relying on defaults:
cordova platform add android@^14.0.1
cordova platform add ios@^7.1.1 # macOS only
Android setup
The Incode Android SDK requires a recent Android toolchain. Set these preferences in your app's config.xml:
<platform name="android">
<preference name="android-compileSdkVersion" value="36" />
<preference name="AndroidGradlePluginVersion" value="8.9.1" />
<preference name="GradleVersion" value="8.14.5" />
<preference name="GradlePluginKotlinEnabled" value="true" />
<preference name="GradlePluginKotlinVersion" value="2.2.21" />
</platform>
The Kotlin plugin is required even in a pure-JavaScript Cordova app, because the plugin ships Kotlin sources. The preference key that cordova-android reads is AndroidGradlePluginVersion. If your config.xml uses android-gradlePluginVersion, it is silently ignored.
Android resolves the Incode native SDK from Incode's GitHub Maven package repository, which requires authentication. Modify your project's build.gradle to include the GitHub Packages repository with credentials provided by Incode.
The Maven repository that hosts the native dependency is:
https://maven.pkg.github.com/Incode-Technologies-Example-Repos/android-omni-packages
Add a hook within the config.xml file inside widget, after your platform element. It will be triggered after platform is added:
<hook type="after_platform_add" src="hooks/after_platform_add/add-incode-maven-repo.js" />
add-incode-maven-repo.js content that can be reused:
#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const repoBlock = `maven {
url = uri("https://maven.pkg.github.com/Incode-Technologies-Example-Repos/android-omni-packages")
credentials {
username = "incode-customers"
password = project.findProperty("github_token") ?: System.getenv("GITHUB_TOKEN")
}
}`;
function removeIncodeMavenBlocks(block) {
let idx = 0;
while (true) {
const mavenIndex = block.indexOf('maven {', idx);
if (mavenIndex === -1) break;
// Only consider blocks containing the Incode repo URL
const urlIdx = block.indexOf('repo.incode.com/artifactory/libs-incode-welcome', mavenIndex);
if (urlIdx === -1) {
idx = mavenIndex + 7;
continue;
}
// Find the matching closing brace for maven { ... }
let braceCount = 0;
let endIdx = mavenIndex;
let found = false;
for (; endIdx < block.length; endIdx++) {
if (block[endIdx] === '{') braceCount++;
else if (block[endIdx] === '}') braceCount--;
if (braceCount === 0 && endIdx > mavenIndex) {
found = true;
break;
}
}
if (found) {
block = block.slice(0, mavenIndex) + block.slice(endIdx + 1);
idx = mavenIndex; // Continue searching after removed block
} else {
break; // Malformed, stop
}
}
return block;
}
function insertRepoFirst(block) {
block = removeIncodeMavenBlocks(block);
return block.replace(/repositories\s*\{/, match => `${match}\n${repoBlock}\n`);
}
function patchGradle(context) {
const projectRoot = context.opts && context.opts.projectRoot ? context.opts.projectRoot : process.cwd();
const appGradlePath = path.join(projectRoot, 'platforms/android/app/build.gradle');
if (!fs.existsSync(appGradlePath)) {
console.log('app/build.gradle not found:', appGradlePath);
return;
}
let appGradle = fs.readFileSync(appGradlePath, 'utf8');
// Patch buildscript
appGradle = appGradle.replace(/(buildscript\s*\{[\s\S]*?)(\n\s*dependencies\s*\{)/, (match, p1, p2) => {
let beforeDeps = p1;
if (/repositories\s*\{/.test(beforeDeps)) {
beforeDeps = insertRepoFirst(beforeDeps);
} else {
beforeDeps = beforeDeps.replace(/buildscript\s*\{/, m => `${m}\n repositories {\n${repoBlock}\n }\n`);
}
return beforeDeps + p2;
});
// Patch allprojects
appGradle = appGradle.replace(/(allprojects\s*\{[\s\S]*?)(\n\s*task |\n\s*ext |\n\s*android |\n\s*\/\*|$)/, (match, p1, p2) => {
let beforeNext = p1;
if (/repositories\s*\{/.test(beforeNext)) {
beforeNext = insertRepoFirst(beforeNext);
} else {
beforeNext = beforeNext.replace(/allprojects\s*\{/, m => `${m}\n repositories {\n${repoBlock}\n }\n`);
}
return beforeNext + p2;
});
fs.writeFileSync(appGradlePath, appGradle, 'utf8');
}
// Cordova will call as a function during the build, but allow running directly for manual testing
module.exports = patchGradle;
if (require.main === module) {
patchGradle({ opts: { projectRoot: process.cwd() } });
}
iOS setup
iOS native dependencies are managed through CocoaPods and are installed when you add the iOS platform. If pod installation fails, run pod repo update and re-add the platform:
cordova platform rm ios && cordova platform add ios@^7.1.1
Initialize the SDK
On startup, call initializeSDK() with your Incode API key and base URL:
cordova.exec(
function () { console.log("SDK ready"); },
function (err) { console.log("Init error:", err); },
"Cplugin",
"initializeSDK",
[
"YOUR_API_KEY", // apiKey
"https://your.api.url", // apiUrl
"true", // loggingEnabled
"false", // testMode
"experimentV2", // clientExperimentId (opts iOS into V2 UI; use null for V1)
"https://your.e2ee.api.url", // e2eeUrl
{ enabled: false, forceSSLPinning: false } // sslPinningConfig
// optional: "standard", "false", "false" — sdkMode, externalAnalyticsEnabled, externalScreenshotsEnabled
]
);
Keep all credentials out of source control. For the full argument breakdown, see the API Reference.