Capacitor Plugin Configuration

Every configuration option for the DeployYourApp Capacitor plugin, with types, defaults, and a full example.


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 — forces immediate, ignoring everything else.
  • delayUntil — an ISO 8601 timestamp, with either a Z or 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.


Previous
Setup
Next
API Reference