# Cordova Custom Config Plugin

For Cordova 5.2 or lower, basic behaviour of Android or iOS applications can be configured by editing `AndroidManifest.xml` or `MonacaApp-Info.plist` file respectively. However, for Cordova 6.2 or higher, both `AndroidManifest.xml` and `MonacaApp-Info.plist` files are removed from Monaca framework.

Therefore, in order to config iOS/Android application settings, you will need to use Cordova Custom Config plugin. This Cordova plugin for iOS and Android provides hook scripts to update platform configuration files based on custom preferences and config-file data defined in `config.xml` file that are not supported out-of-the-box by Cordova.

## Changes in Cordova Custom Config Plugin v5

The recent release of cordova\@7.0.0 has introduced backwardly-incompatible breaking changes to the structure of Android projects generated by Cordova.

Therefore a new major version of this plugin (v5) has been released to support these changes. Here are things to be aware of:

1. The location of AndroidManifest.xml has changed in cordova-android\@7 but cordova-custom-config\@5 should detect which version of cordova-android platform is present in the project and use the correct path.
2. All custom config elements supported by this plugin in config.xml should now be prefixed with custom- for use with cordova-custom-config\@5
   * `<config-file>` => `<custom-config-file>`
   * `<preference>` => `<custom-preference>`
   * `<resource>` => `<custom-resource>`
   * This is because cordova-android\@7 now attempts to parse `<config-file>` blocks in the config.xml, so `<config-file>` blocks intended for this plugin to parse will be picked up by Cordova and can cause build errors (see [#135](https://github.com/dpa99c/cordova-custom-config/issues/135)) for an example.
   * [Plugin preferences](/reference/third_party_phonegap/custom_config.md#plugin-preferences) should still however be specified as `<preference>`

     ```markup
     <preference name="cordova-custom-config-autorestore" value="true" />
     ```
   * The plugin will detect if the platform project is cordova-android\@7 or cordova-android\@6 (or below)
     * If cordova-android\@6, by default the plugin will support non-prefixed custom config elements
     * If cordova-android\@7, by default the plugin will NOT support non-prefixed custom config elements
     * This can be overridden by explicitly setting the `parse_unprefixed` preference

       ```markup
       <preference name="cordova-custom-config-parse_unprefixed" value="true" />
       ```

## Enable the Plugin in Monaca

1. From the IDE menu, go to `Configure → Cordova Plugin Settings`.
2. Under *Available Plugins* section, hover over the `Custom Config` plugin and click `Enable` button.

![](/files/-Mff1UjDYdpGV9mOHkZA)

## Usage

There are no run-time source files included in this plugin. It includes hook scripts which are used to apply preferences dictated by custom keys in the `config.xml` file of the project to the relevant platform config files. Therefore, in order to use this plugin, you need to include the relevant keys in your `config.xml` and the scripts will take care of the rest when you build your project.

By default, any changes made by this plugin to platform config files are irreversible. However, if you want the changes made to be reversible, you can enable auto-backup/restore functionality by adding the following preference inside the top-level `<widget>` element of your `config.xml`:

```markup
<preference name="cordova-custom-config-autorestore" value="true" />
```

## Preferences

Preferences are set by defining a `<preference>` element in the `config.xml` file. For example:

```markup
<custom-preference name="android-launchMode" value="singleTop" />
```

While setting the preferences, please be aware of the following points:

1. Preferences defined outside of the `<platform>` element will apply

   to all platforms.
2. Preferences defined inside a `<platform>` element will apply only to

   the specified platform.
3. Platform preferences take precedence over common preferences.
4. Platform-specific preferences must be prefixed with the platform

   name (e.g. `name="ios-somepref"`) and be defined inside a `<platform>`

   element.

## Config Blocks

`<config-file>` blocks allow platform-specific chunks of the configuration to be defined as an XML subtree in the `config.xml` file, which is then applied to the appropriate platform configuration file by the plugin.

While setting the config blocks, please be aware of the following points:

1. `<config-file>` elements must be defined inside a `<platform>`

   element, otherwise they will be ignored.
2. config-file `target` attributes specify the target file to update.

   (`AndroidManifest.xml` or `*-Info.plist`)
3. config-file `parent` attributes specify the parent element

   (`AndroidManifest.xml`) or parent key (`*-Info.plist`) that the

   child data will replace or be appended to.
4. `<config-file>` elements are uniquely indexed by target and parent

   for each platform.
5. If there are multiple config-file's defined with the same target and

   parent, the last config-file will be used.
6. Elements defined within a config-file will replace or be appended to

   the same elements relative to the parent element.
7. If a unique config-file contains multiples of the same elements

   (other than `<uses-permission>` elements which are selected by by

   the uses-permission `name` attribute), the last defined element will

   be retrieved.

## Android

The plugin currently supports setting of custom config only in `platforms/android/AndroidManifest.xml`. For a list of possible manifest values, please refer to [App Manifest](http://developer.android.com/guide/topics/manifest/manifest-intro.html). All Android-specific config should be placed inside the `<platform name="android">` in `config.xml` file.

### Android Preferences

`<preference>` elements in `config.xml` are used to set attributes on elements in the `AndroidManifest.xml`. For example, if you add the following element to the `config.xml`:

```markup
<custom-preference name="android-manifest/@android:hardwareAccelerated" value="false" />
```

then the following line will be added to `AndroidManifest.xml`:

```markup
<manifest android:hardwareAccelerated="false">
```

Sometimes, you may want to remove some default settings in `AndroidManifest.xml`. You can do delete them by using the `delete="true"` attribute of the `<preference>` element. For example, if you add the following line in `config.xml`, it will delete the existing node `<uses-permission android:name="android.permission.WRITE_CONTACTS" />` within `AndroidManifest.xml`:

```markup
<custom-preference name="android-manifest/uses-permission/[@android:name='android.permission.WRITE_CONTACTS']" delete="true" />
```

#### Android Namespace Attribute

{% hint style="info" %}
In order to user the `android:` namespace in preferences within your `config.xml`, you must include the android namespace attribute on the root `<widget>` element.
{% endhint %}

The namespace attribute fragment is:

```markup
xmlns:android="http://schemas.android.com/apk/res/android"
```

so your `<widget>` element should look something like this:

```markup
<widget
    id="com.my.app"
    version="0.0.1"
    xmlns="http://www.w3.org/ns/widgets"
    xmlns:cdv="http://cordova.apache.org/ns/1.0"
    xmlns:android="http://schemas.android.com/apk/res/android">
```

#### XPath Preferences

Android manifest preferences are set by using XPaths in the preference name to define which element attribute the value should be applied to. The preference name should be prefixed with `android-manifest` then follow with an XPath which specifies the element and attribute to apply the value to. For example,

```markup
<custom-preference name="android-manifest/application/activity/@android:launchMode" value="singleTask" />
```

This preference specifies that the `launchMode` attribute should be given a value of `singleTask` which will be resulted as:

```markup
<activity android:launchMode="singleTask">
```

If your manifest contains other activities, you should specify the activity name in the XPath. For example:

```markup
<custom-preference name="android-manifest/application/activity[@android:name='MainActivity']/@android:launchMode" value="singleTask" />
```

{% hint style="info" %}
The activity name for Cordova 4.2.0 and below was `CordovaApp` whereas Cordova 4.3.0 and above is `MainActivity`.
{% endhint %}

If the attribute you are setting is on the root `<manifest>` element, just omit the element name and specify the attribute. For example:

```markup
<custom-preference name="android-manifest/@android:installLocation" value="auto" />
```

### Android Config Blocks

`<config-file>` blocks are used to define chunks of configuration of an XML subtree which will be inserted into `AndroidManifest.xml`. The child elements inside the `<config-file>` block will be inserted under the parent element.

`<config-file>` element has two attributes such as:

1. `target`: must be set to `AndroidManifest.xml`.
2. `parent`: defines an Xpath to the parent element in the `AndroidManifest.xml` under which the XML subtree block should be inserted:
   * to insert a block under the root `<manifest>` element, use `parent="/*"`.
   * to insert a block under a descendant of `<manifest>`, use an Xpath prefixed with `./`. For example, `parent="./application/activity"` will insert the block under `/manifest/application/activity`.

For example:

```markup
<config-file target="AndroidManifest.xml" parent="./application">
    <some-element />
</config-file>
```

will result in `AndroidManifest.xml` with:

```markup
<manifest ...>
    <application ...>
        <some-element />
    </application>
</manifest>
```

{% hint style="info" %}
If the specified parent element contains an existing child element of the same name as that defined in the XML subtree, the existing element will be overwritten.
{% endhint %}

For example:

```markup
<config-file target="AndroidManifest.xml">
    <application android:name="MyApp" />
</config-file>
```

will replace the existing `<application>` element. In this case, it would be better to use a preference:

```markup
<preference name="android-manifest/application/@android:name" value="MyApp" />
```

### Android Example

Below is an example of a `config.xml` file for Android configuration:

```markup
<platform name="android">
    <!-- custom preferences examples -->
    <custom-preference name="android-manifest/application/activity/@android:windowSoftInputMode" value="stateVisible" />
    <custom-preference name="android-manifest/@android:installLocation" value="auto" />
    <custom-preference name="android-manifest/application/@android:hardwareAccelerated" value="false" />
    <custom-preference name="android-manifest/@android:hardwareAccelerated" value="false" />
    <custom-preference name="android-manifest/application/activity/@android:configChanges" value="orientation" />
    <custom-preference name="android-manifest/application/activity/@android:theme" value="@android:style/Theme.Material" />

    <!-- specify activity name -->
    <custom-preference name="android-manifest/application/activity[@android:name='MainActivity']/@android:launchMode" value="singleTask" />

    <!-- Delete an element -->
    <custom-preference name="android-manifest/application/activity[@android:name='DeleteMe']" delete="true" />


    <!-- These preferences are actually available in Cordova by default although not currently documented -->
    <custom-preference name="android-minSdkVersion" value="10" />
    <custom-preference name="android-maxSdkVersion" value="22" />
    <custom-preference name="android-targetSdkVersion" value="21" />

    <!-- Or you can use a custom-config-file element for them -->
    <custom-config-file target="AndroidManifest.xml" parent="/*">
        <uses-sdk android:maxSdkVersion="22" android:minSdkVersion="10" android:targetSdkVersion="21" />
    </custom-config-file>


    <!-- custom config example -->
     <custom-config-file target="AndroidManifest.xml" parent="/*">
        <supports-screens
            android:xlargeScreens="false"
            android:largeScreens="false"
            android:smallScreens="false" />

        <uses-permission android:name="android.permission.READ_CONTACTS" android:maxSdkVersion="15" />
        <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    </custom-config-file>

    <!-- Add (rather than overwrite) a custom-config-file block -->
    <custom-config-file target="AndroidManifest.xml" parent="./" mode="add">
        <application android:name="customApplication"></application>
    </custom-config-file>

</platform>
```

## iOS

The plugin currently supports custom configuration of the project plist (`*-Info.plist`) using config blocks, and project settings (`project.pbxproj`) using preference elements. All iOS-specific config should be placed inside the `<platform name="ios">` in `config.xml` file.

### iOS Preferences

`<preference>` elements in `config.xml` are used to set preferences in the `*-Info.plist`. Preferences should be defined in the format: `<preference name="ios-SOME_BLOCK_TYPE-SOME_KEY" value="SOME_VALUE" />`. For example:

```markup
<custom-preference name="ios-XCBuildConfiguration-ENABLE_BITCODE" value="YES" />/>
```

#### Build Configuration Preferences

Currently, `XCBuildConfiguration` is the only supported block type in the `project.pbxproj`. However, there is no constraint on the list of keys for which values may be set.

If an entry already exists in an `XCBuildConfiguration` block for the specified key, the existing value will be overwritten with the specified value. If no entry exists in any `XCBuildConfiguration` block for the specified key, a new key entry will be created in each `XCBuildConfiguration` block with the specified value.

By default, values will be applied to both "Release" and "Debug" `XCBuildConfiguration` blocks. However, the block type can be specified by adding a `buildType` attribute to the `<preference>` element in the `config.xml`. The value can be either `debug` or `release`. For example:

```markup
<custom-preference name="ios-XCBuildConfiguration-IPHONEOS_DEPLOYMENT_TARGET" value="7.0" buildType="release" />
```

By default, both the key (preference name) and value will be quote-escaped when inserted into the `XCBuildConfiguration` block. For example:

```markup
<custom-preference name="ios-XCBuildConfiguration-IPHONEOS_DEPLOYMENT_TARGET" value="7.0" buildType="release" />
```

will appear in `project.pbxproj` as:

```markup
"IPHONEOS_DEPLOYMENT_TARGET" = "7.0";
```

The default quoting can be override by setting the `quote` attribute on the `<preference>` element. The valid values are:

* `none`: don't quote key or value
* `key`: quote key but not value
* `value`: quote value but not key
* `both`: quote both key and value

For example:

```markup
<custom-preference name="ios-XCBuildConfiguration-IPHONEOS_DEPLOYMENT_TARGET" value="7.0" buildType="release" quote="none" />
```

will appear in `project.pbxproj` as:

```markup
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
```

#### .xcconfig files

Cordova uses `.xcconfig` files in `/platforms/ios/cordova/` to override Xcode project settings in `project.pbxproj` with build-type specific values. `build.xcconfig` is overridden by settings in `build-debug.xcconfig` and `build-release.xcconfig` for the corresponding build type.

When applying a custom preference, the plugin will look for an existing entry in the `.xcconfig` file that corresponds to the buildType attribute.

* If buildType attribute is `debug` or `release`, the plugin will

  look in `build-debug.xcconfig` or `build-release.xcconfig`

  respectively.
* If buildType is not specified or set to `none`, the plugin will

  look in `build.xcconfig`.

By default, if an entry is found in the `.xcconfig` file which corresponds to the custom preference name in the `config.xml`, the value in the `.xcconfig` file will be overwritten with the value in the `config.xml`. To prevent the plugin from overwriting the value of a specific preference in the corresponding `.xcconfig` file, set the preference attribute `xcconfigEnforce="false"`. For example:

```markup
<custom-preference name="ios-XCBuildConfiguration-SOME_PREFERENCE" value="Some value" buildType="debug" xcconfigEnforce="false" />
```

If a preference value doesn't already exist in the corresponding `.xcconfig` file, you can force its addition by setting the preference attribute `xcconfigEnforce="true"`. This will append it to the corresponding `.xcconfig` file. For example:

```markup
<custom-preference name="ios-XCBuildConfiguration-SOME_PREFERENCE" value="Some value" buildType="debug" xcconfigEnforce="true" />
```

A backup copy of any modified `.xcconfig` file will be made in `plugins/cordova-custom-config/backup/ios`. By default, these backups will be restored prior to the next prepare operation. Auto-restore of the backups can be disabled by setting `<preference name="cordova-custom-config-autorestore" value="false" />` in the `config.xml`.

Preference names and values will not be quote-escaped in `.xcconfig` files, so the `quote` attribute has no effect on them.

#### CODE\_SIGN\_IDENTITY preferences

Cordova places its default CODE\_SIGN\_IDENTITY for Release builds in `build-release.xcconfig` but for Debug builds in `build.xcconfig`.

If you set a CODE\_SIGN\_IDENTITY preference in the `config.xml` with `buildType="release"`, the plugin will overwrite the defaults in `build-release.xcconfig`. For example:

```markup
<custom-preference name="ios-XCBuildConfiguration-CODE_SIGN_IDENTITY" value="iPhone Distribution: My Release Profile (A1B2C3D4)" buildType="release" />
```

If you set a CODE\_SIGN\_IDENTITY preference in the `config.xml` with `buildType="debug"`, the plugin will overwrite the defaults in `build.xcconfig`. For example:

```markup
<custom-preference name="ios-XCBuildConfiguration-CODE_SIGN_IDENTITY" value="iPhone Distribution: My Debug Profile (A1B2C3D4)" buildType="debug" />
```

You can prevent the CODE\_SIGN\_IDENTITY preferences being overwritten by setting `xcconfigEnforce="false"`. For example:

```markup
<custom-preference name="ios-XCBuildConfiguration-CODE_SIGN_IDENTITY" value="iPhone Distribution: My Release Profile (A1B2C3D4)" buildType="release" xcconfigEnforce="false" />
```

You can force the plugin to add a new entry for CODE\_SIGN\_IDENTITY preference with `buildType="debug"` to `build-debug.xcconfig`, rather than overwriting the defaults in `build.xcconfig` by setting `xcconfigEnforce="true"`. This will still override the defaults in `build.xcconfig`, because `build-debug.xcconfig` overrides `build.xcconfig`. For example:

```markup
<custom-preference name="ios-XCBuildConfiguration-CODE_SIGN_IDENTITY" value="iPhone Distribution: My Debug Profile (A1B2C3D4)" buildType="debug" xcconfigEnforce="true" />
```

### iOS Config Blocks

`<config-file>` elements are currently only used to set preferences in the project `.plist` file (`platforms/ios/{PROJECT_NAME}/{PROJECT_NAME}-Info.plist`). This element has 3 attributes such as:

1. `target`: should be set to `*-Info.plist`.
2. `platform`: should be set to `ios`.
3. `parent`: is used to determine which key name to use for the custom

   preference.

For example:

```markup
<config-file platform="ios" target="*-Info.plist" parent="NSLocationAlwaysUsageDescription">
```

will result in `{PROJECT_NAME}-Info.plist` as:

```markup
<plist version="1.0">
    <dict>
        <key>NSLocationAlwaysUsageDescription</key>
    </dict>
</plist>
```

The value of the preference is set by the child elements of the `<config-file>` element. These will appear directly below the preference `<key>` in the `.plist` file.

For example:

```markup
<config-file platform="ios" target="*-Info.plist" parent="NSLocationAlwaysUsageDescription">
    <string>
        This app requires constant access to your location in order to track your position, even when the screen is off.
    </string>
</config-file>
```

will appear in the `plist` file as:

```markup
<key>
    NSLocationAlwaysUsageDescription
</key>
<string>
    This app requires constant access to your location in order to track your position, even when the screen is off.
</string>
```

### iOS Example

Below is an example of a `config.xml` file for iOS configuration:

```markup
<platform name="ios">

    <!-- Set ENABLE_BITCODE to YES in XCode project file override NO value in /ios/cordova/build.xcconfig -->
    <custom-preference name="ios-XCBuildConfiguration-ENABLE_BITCODE" value="YES" />

    <!-- Set deploy target SDKs for release and debug builds -->
    <custom-preference name="ios-XCBuildConfiguration-IPHONEOS_DEPLOYMENT_TARGET" value="9.1" buildType="debug" quote="none" />
    <custom-preference name="ios-XCBuildConfiguration-IPHONEOS_DEPLOYMENT_TARGET" value="7.0" buildType="release" />

    <!-- Custom code signing profiles (overriding those in /ios/cordova/*.xcconfig -->
    <custom-preference name="ios-XCBuildConfiguration-CODE_SIGN_IDENTITY" value="iPhone Developer: Dave Alden (8VUQ6DYDLL)" buildType="debug" xcconfigEnforce="true" />
    <custom-preference name="ios-XCBuildConfiguration-CODE_SIGN_IDENTITY[sdk=iphoneos*]" value="iPhone Developer: Dave Alden (8VUQ6DYDLL)" buildType="debug" />
    <custom-preference name="ios-XCBuildConfiguration-CODE_SIGN_IDENTITY[sdk=iphoneos9.1]" value="iPhone Developer: Dave Alden (8VUQ6DYDLL)" buildType="debug" />
    <custom-preference name="ios-XCBuildConfiguration-CODE_SIGN_IDENTITY" value="iPhone Distribution: Working Edge Ltd (556F3DRHUD)" buildType="release" xcconfigEnforce="false" />
    <custom-preference name="ios-XCBuildConfiguration-CODE_SIGN_IDENTITY[sdk=iphoneos*]" value="iPhone Distribution: Working Edge Ltd (556F3DRHUD)" buildType="release" />
    <custom-preference name="ios-XCBuildConfiguration-CODE_SIGN_IDENTITY[sdk=iphoneos9.1]" value="iPhone Distribution: Working Edge Ltd (556F3DRHUD)" buildType="release" />

    <!-- Add resource file by relative path -->
    <custom-preference name="ios-xcodefunc" func="addResourceFile">
        <arg type="String" value="src/content/image.png" flag="path" />
    </custom-preference>

   <!-- By default, merge with existing array values -->
   <custom-config-file parent="LSApplicationQueriesSchemes" target="*-Info.plist">
       <array>
           <string>myapp</string>
           <string>myapp2</string>
           <string>myapp3</string>
       </array>
   </custom-config-file>

   <!-- Explicitly merge with existing array values -->
   <custom-config-file platform="ios" target="*-Info.plist" parent="UISupportedInterfaceOrientations" mode="merge" >
       <array>
           <string>UIInterfaceOrientationPortrait</string>
           <string>UIInterfaceOrientationPortraitUpsideDown</string>
       </array>
   </custom-config-file>

   <!-- Replace existing values -->
   <custom-config-file platform="ios" target="*-Info.plist" parent="UISupportedInterfaceOrientations~ipad" mode="replace">
       <array>
           <string>UIInterfaceOrientationPortrait</string>
           <string>UIInterfaceOrientationPortraitUpsideDown</string>
       </array>
   </custom-config-file>

    <!-- Set background location mode -->
    <custom-config-file platform="ios" target="*-Info.plist" parent="UIBackgroundModes">
        <array>
            <string>location</string>
        </array>
    </custom-config-file>

    <!-- Set message displayed when app requests constant location updates -->
    <custom-config-file platform="ios" target="*-Info.plist" parent="NSLocationAlwaysUsageDescription">
        <string>This app requires constant access to your location in order to track your position, even when the screen is off.</string>
    </custom-config-file>

    <!-- Set message displayed when app requests foreground location updates -->
    <custom-config-file platform="ios" target="*-Info.plist" parent="NSLocationWhenInUseUsageDescription">
        <string>This app will now only track your location when the screen is on and the app is displayed.</string>
    </custom-config-file>

    <!-- Allow arbitrary loading of resources over HTTP on iOS9 -->
    <custom-config-file platform="ios" target="*-Info.plist" parent="NSAppTransportSecurity">
        <dict>
            <key>NSAllowsArbitraryLoads</key>
            <true/>
        </dict>
    </custom-config-file>

    <!-- Custom image asset catalog -->
    <custom-resource type="image" catalog="custom" src="resources/ios/custom-icons/back@1x.png" scale="1x" idiom="universal" />
    <custom-resource type="image" catalog="custom" src="resources/ios/custom-icons/back@2x.png" scale="2x" idiom="universal" />
    <custom-resource type="image" catalog="custom" src="resources/ios/custom-icons/back@3x.png" scale="3x" idiom="universal" />
</platform>
```

## Plugin Preferences

The plugin supports some preferences which are used to customize the behavior of the plugin. Each preference name is prefixed with `cordova-custom-config` to avoid name clashes. For example:

```markup
<preference name="cordova-custom-config-autorestore" value="true" />
```

The following preferences are currently supported:

* `cordova-custom-config-autorestore`: (set to `false` by default) if set to `true`, the plugin will restore a backup of platform configuration files taken at plugin installation time.
* `cordova-custom-config-stoponerror`: (set to `false` by default) if set to `true` and an error occurs while updating config for a given platform during a `prepare` operation, the error will cause the `prepare` operation to fail. If false, the plugin will log the error but will proceed and attempt to update any other platforms, before allowing the prepare operation to continue.

See Also:

* [Core Cordova Plugins](/reference/core-cordova-plugins.md)
* [Monaca Power Plugins](/reference/power_plugins.md)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://en.docs.monaca.io/reference/third_party_phonegap/custom_config.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
