Complete reference for the plugins.DeployYourApp block in your Capacitor config, plus the settings you can change at runtime.
Where configuration lives
The plugin reads its configuration from the Capacitor config file — capacitor.config.json, capacitor.config.js, or capacitor.config.ts — under plugins.DeployYourApp. Native code reads it at plugin load, so changing it requires a rebuild of the native app, not just a new web bundle.
{
"plugins": {
"DeployYourApp": {
"appId": "com.yourcompany.yourapp",
"channel": "production"
}
}
}
Options
| Option | Type | Default | Description |
|---|---|---|---|
appId |
string | required | Your app ID from the DeployYourApp dashboard. When unset, falls back to the iOS bundle identifier or the Android package name and logs a warning; update checks then only match if that identifier is your app ID. |
updateUrl |
string | https://api.deployyour.app |
Update server base URL. The plugin appends /api/update — do not include a path. |
statsUrl |
string | https://api.deployyour.app |
Analytics server base URL. The plugin appends /api/stats — do not include a path. |
allowedDownloadHosts |
string[] | ['storage.deployyour.app'] |
Extra hosts allowed to serve bundle downloads. The updateUrl and statsUrl hosts are always allowed, so this is only needed when bundles come from a different host, such as a CDN. Downloads are https-only (http from localhost alone); anything else rejects with INVALID_URL. |
channel |
string | production |
Update channel to check. A channel previously set with setChannel() takes precedence over this value. |
autoUpdate |
boolean | true |
Check on launch and every checkInterval seconds, download new bundles, and activate them according to applyMode. |
applyMode |
string | whenIdle |
When a downloaded update becomes active. One of whenIdle, immediate, onLaunch, background. See applyMode. |
checkInterval |
number | 600 |
Seconds between automatic update checks. 0 disables the repeating timer; the launch check still runs. |
appReadyTimeout |
number | 10000 |
Milliseconds a newly served bundle has to call notifyAppReady() before the plugin rolls back. |
publicKey |
string | unset | RSA public key (PEM, SPKI — -----BEGIN PUBLIC KEY-----) used to verify bundle signatures. |
encryptionPrivateKey |
string | unset | RSA private key (PEM, PKCS#8 — -----BEGIN PRIVATE KEY-----) used to unwrap the AES session key of an end-to-end encrypted bundle. |
analyticsEnabled |
boolean | true |
Collect and send analytics events. false stops all /api/stats traffic, including the plugin's own update_* events. |
analyticsBatchSize |
number | 20 |
Buffered events that trigger an immediate flush. |
analyticsFlushInterval |
number | 30 |
Seconds between automatic analytics flushes. |
autoDeleteFailed |
boolean | true |
Delete a bundle from disk when it is rolled back. |
autoDeletePrevious |
boolean | true |
Delete the previous bundle once the new one is confirmed by notifyAppReady(). |
resetWhenUpdate |
boolean | true |
Reset to the built-in bundle when the native app version changes (for example a store update), and emit appVersionChange. |
enableTestGesture |
boolean | false |
Detect a three-finger tap on the webview and emit testGestureTrigger. Used by the corporate app shell. |
directUpdate |
string | whenIdle |
Deprecated alias for applyMode. See directUpdate. |
Full example
// capacitor.config.js
export default {
appId: 'com.yourcompany.yourapp',
appName: 'Your App',
webDir: 'dist',
plugins: {
DeployYourApp: {
// Identity
appId: 'com.yourcompany.yourapp',
channel: 'production',
// Servers (only needed to target a non-default environment)
updateUrl: 'https://api.deployyour.app',
statsUrl: 'https://api.deployyour.app',
// Update behaviour
autoUpdate: true,
applyMode: 'whenIdle',
checkInterval: 600,
appReadyTimeout: 10000,
resetWhenUpdate: true,
// Verification and decryption
publicKey: '-----BEGIN PUBLIC KEY-----\nMIICIjANBg...\n-----END PUBLIC KEY-----\n',
encryptionPrivateKey: '-----BEGIN PRIVATE KEY-----\nMIIJQwIBAD...\n-----END PRIVATE KEY-----\n',
// Analytics
analyticsEnabled: true,
analyticsBatchSize: 20,
analyticsFlushInterval: 30,
// Storage housekeeping
autoDeleteFailed: true,
autoDeletePrevious: true,
// Corporate shell
enableTestGesture: false,
},
},
};
applyMode
applyMode decides when a downloaded bundle actually takes effect. It only governs the automatic flow — an explicit apply() call always activates the bundle immediately.
| Value | Behaviour |
|---|---|
whenIdle |
Download in the background, stage the bundle, activate it on the next app launch. This is the default. |
onLaunch |
Download in the background, hold the bundle as pending, activate it on the next app launch. |
background |
Download only and emit downloadComplete. Nothing is activated until your app calls apply(). |
immediate |
Download, activate, and reload the webview during the current session. |
whenIdle and onLaunch both activate on the next launch. They differ only in bookkeeping: whenIdle stages the bundle right away, while onLaunch holds it as pending and stages it during the next launch.
Three server-controlled fields on the update-check response override the local setting for that one update:
applyMode— takes precedence over the configured value.mandatory: true— forcesimmediate, ignoring everything else.delayUntil— an ISO 8601 timestamp, with either aZor a numeric UTC offset. While it is in the future, the bundle is downloaded and held; it is staged by the first launch or update check after the timestamp passes. A timestamp the plugin cannot parse is treated as a deferral to the next launch — never as "apply now" — and logged.
An unrecognised applyMode string is treated as whenIdle.
directUpdate (deprecated)
directUpdate is the legacy name for applyMode. It is only consulted when applyMode is absent: "immediate" maps to immediate, and every other value maps to whenIdle. Use applyMode.
Runtime settings
Three values are stored on the device and outlive the config file. They are read by every update check.
| Setting | Set with | Read with | Storage |
|---|---|---|---|
| Channel | setChannel({ channel }) |
getChannel() |
UserDefaults (iOS), dya_config preferences (Android), localStorage (web) |
| Custom device ID | setCustomId({ customId }) |
not readable from JavaScript | UserDefaults / dya_prefs / localStorage |
| Version override | setVersionOverride({ version }) |
getVersionOverride() |
UserDefaults / dya_prefs / localStorage |
Once setChannel() has run on a device, the stored channel wins over the channel value in the config file on every subsequent launch. To move a device back, call setChannel() again with the original name.
The version override replaces the reported bundle version in update checks, which is useful for testing targeting rules without shipping a bundle. Pass an empty string to clear it.
await DeployYourApp.setChannel({ channel: 'beta' });
await DeployYourApp.setVersionOverride({ version: '0.0.1' });
// ...
await DeployYourApp.setVersionOverride({ version: '' });
Keys
dya keys generate writes four RSA-4096 PEM files. Two of them belong in this config:
| File | Config option | Notes |
|---|---|---|
dya-signing-public.pem |
publicKey |
Verifies the signature dya deploy produces with dya-signing-private.pem. |
dya-encryption-private.pem |
encryptionPrivateKey |
Unwraps the AES-256-GCM session key of bundles encrypted with dya-encryption-public.pem. |
Signature verification only runs when publicKey is configured and the server sent a signature; otherwise the download proceeds on the checksum alone. If the server sends a signature but no publicKey is configured, the bundle is applied unverified and the plugin logs a warning naming the version — configure publicKey to close that gap. Decryption only runs when the server sends a sessionKey, and fails with DECRYPTION_FAILED if encryptionPrivateKey is not configured.
Embedding encryptionPrivateKey in the Capacitor config puts a private key in your source tree. Keep that file out of public repositories. See Encryption and bundle signing.
Turning off network traffic
analyticsEnabled: false stops all traffic to /api/stats, including the update lifecycle events the plugin records on its own. To stop contacting the update server as well, set autoUpdate: false and do not call checkForUpdate():
{
"plugins": {
"DeployYourApp": {
"appId": "com.yourcompany.yourapp",
"analyticsEnabled": false,
"autoUpdate": false
}
}
}
What each endpoint receives is listed in SDK data collection.