Platforms: iOS, Android
Many software development teams utilize different environments during the software development lifecycle. Configuration may differ between environments, such as bundle IDs, deep-link schemes, or icons and splash screens.
The Capacitor configuration file handles high-level options for Capacitor tooling and plugin configuration. iOS schemes and Android product flavors allow developers to provide differing app values for different environments. By combining the two, developers can use the Capacitor CLI to build apps for different environments.
This guide will walk you through setting up a QA environment configuration alongside the default environment configuration provided out-of-the-box. To demonstrate differences between each environment, the app name and bundle ID will differ between the two.
You will need a Capacitor app with both iOS and Android platforms added. If you have an existing Capacitor app with both platforms added, skip this section.
Depending on your preference, you can either add Capacitor to an existing web application or create a new Capacitor application with the Ionic Framework.
The Capacitor app must use TypeScript for configuration. This guide uses
capacitor.config.ts
to dynamically export different configurations.
Before adding any native platforms to the project, you must build the Capacitor App at least once.
npm run build
Once built, you can add the platforms.
npm install @capacitor/ios @capacitor/android
npx cap add ios
npx cap add android
Start by opening the native iOS project in Xcode:
npx cap open ios
.
Enter
key to rename it. Set the target’s name to “App QA”.This process created an additional “App copy” scheme and added a new file called
App copy-Info.plist
.
You can find additional information on iOS targets at this link.
Enter
key to rename it. Set the name to “App QA” and close the dialog.Enter
key to rename it. Set the file’s name to “App QA-Info.plist”.The iOS project now has two runnable schemes: “App” and “App QA”. Capacitor’s configuration file allows you to supply which scheme to build during the
run
command.
You can find additional information on iOS schemes at this link.
Return to the General portion of the project’s settings. Ensure you have the “App QA” target selected and change the Display Name and Bundle Identifier.
Make sure these values are different than what exists for the default “App” target. Target-specific values get stored in the target’s associated
Info.plist
file. Following this guide, that file is
App QA-Info.plist
.
Exit Xcode; you can use your preferred IDE going forward.
Open /ios/App/Podfile
and duplicate the code block for the “App” target, replacing “App” with “App QA” for the duplicate entry like so:
...snip...
target 'App' do
capacitor_pods
# Add your Pods here
end
target 'App QA' do
capacitor_pods
# Add your Pods here
end
Run npx cap sync
to sync plugins with the “App QA” target.
With the target and scheme for the QA environment created, the Capacitor configuration needs to be updated to use them.
Add the property below to the configuration object in
capacitor.config.ts
:
ios: {
scheme: 'App QA',
}
The scheme
property tells Capacitor which iOS scheme to use for the
run
command. Test this out; run
npx cap run ios
and you’ll see that the app name is different.
Android projects contain multiple build.gradle
files; the one to modify to set up product flavors resides in the
/android/app
folder.
Open /android/app/build.gradle
and add the following code within the
android
block:
flavorDimensions "environment"
productFlavors {
dev {
dimension "environment"
manifestPlaceholders = [displayName:"My App"]
}
qa {
dimension "environment"
applicationIdSuffix ".qa"
manifestPlaceholders = [displayName:"My App - QA"]
}
}
This code requires some explanation:
applicationIdSuffix
will append
.qa
to the end of the bundle ID.manifestPlaceholders
are values that are usable in
AndroidManifest.xml
.Note: You are free to modify the bundle ID and display name values to your liking.
You can find additional information on Android product flavors at this link.
In the last section, you created a placeholder, displayName
. Open AndroidManifest.xml
and change the value of android:label
to ${displayName}
within the
application
and
activity
nodes.
<application
...snip...
android:label="${displayName}">
<activity
...snip...
android:label="${displayName}">
Like iOS, you must update the Capacitor configuration to use the QA product flavor.
Add the property below to the configuration object in
capacitor.config.ts
:
android: {
flavor: "qa",
},
Test this out; run
npx cap run android
and you’ll see that the app name is different.
All the pieces in place, now
capacitor.config.ts
can be written such that it exports a different configuration object based on a particular value.
Open
capacitor.config.ts
and modify the code like so:
import { CapacitorConfig } from '@capacitor/cli';
let config: CapacitorConfig;
const baseConfig: CapacitorConfig = {
appId: 'io.ionic.starter',
appName: 'My App',
webDir: 'build',
bundledWebRuntime: false,
};
switch (process.env.NODE_ENV) {
case 'qa':
config = {
...baseConfig,
ios: {
scheme: 'App QA',
},
android: {
flavor: 'qa',
},
};
break;
default:
config = {
...baseConfig,
ios: {
scheme: 'App',
},
android: {
flavor: 'dev',
},
};
break;
}
export default config;
When
NODE_ENV
equals
qa
, Capacitor will use configuration pointing to the “App QA” scheme and “qa” product flavor. Otherwise, Capacitor uses configuration pointing to the “App” scheme and the “dev” product flavor.
You can run a build using the QA environment-specific configuration by prepending
NODE_ENV=qa
to the npx cap copy
and npx cap run
commands.
NODE_ENV=qa npx cap copy
NODE_ENV=qa npx cap run ios #NODE_ENV=qa npx cap run android
To run a build using the “default” environment-specific configuration, use the Capacitor commands as you would normally.
npx cap copy
npx cap run ios #npx cap run android
Go ahead and test it out! If you’ve followed the guide correctly, you’ll be able to run builds for both environments and see that the app name differs depending on the environment-specific configuration used.
Use the information provided in this guide as a foundation to build upon. The Capacitor CLI has no limitation on how many schemes or product flavors can be used, and you can configure each one as deep as iOS and Android allow you to. You can also provide different environment-specific configuration values for Capacitor plugins! The sky’s the limit.