Readme · Guides · Reference · Contributing
Pre-release. API surface is not yet stable.
This is the native Android reference implementation for the
Contentful Optimization Android SDK. It demonstrates the
integration pattern for both Jetpack Compose (:compose) and XML Views (:views), and is the
target for the shared Maestro E2E suite (see
maestro/README.md).
OptimizationRoot initialization with mock server configurationOptimizedEntry personalization with view and click trackingScreenTrackingEffectPreviewPanelConfig preview panel with audience/variant override controlsThe app defines one locale in shared config, passes it to the native SDK as top-level locale, and
passes it directly to the raw CDA fetch helper. Entries passed to OptimizedEntry use the standard
single-locale CDA entry shape. Do not use all-locale CDA responses or locale=*, because SDK entry
resolution expects direct single-locale fields such as fields.nt_experiences and
fields.nt_variants. See
Locale handling in the Optimization SDK Suite
for the broader locale model and
Entry personalization and variant resolution
for the entry contract.
This mock app uses one Contentful locale. A production app can derive the application locale from
its own navigation, i18n, or account-preference layer and pass that value to both SDK locale and
CDA requests when they should stay aligned.
ANDROID_HOME setadb in PATHpnpm install)pnpm --filter @contentful/optimization-js-bridge buildFrom the monorepo root:
pnpm install
pnpm --filter @contentful/optimization-js-bridge build
The bootstrap script starts the mock server, builds the app, and launches it on an emulator:
cd implementations/android-sdk
./scripts/bootstrap.sh
Or manually:
# Terminal 1: Start mock server
pnpm serve:mocks
# Terminal 2: Build and install (the app reaches the host mock via 10.0.2.2 — no adb reverse needed)
cd implementations/android-sdk
./gradlew :compose:assembleDebug
adb install -r compose/build/outputs/apk/debug/compose-debug.apk
adb shell am start -n com.contentful.optimization.app/.MainActivity
To launch with a clean SDK state (clears the persisted profile on cold start):
adb shell am start -n com.contentful.optimization.app/.MainActivity --ez reset true
Open this directory (implementations/android-sdk/) as an Android Studio project. After Gradle
sync, build and launch either app on the selected device (MainActivity in :compose or :views),
set breakpoints in the app or SDK source, and run the JVM unit tests from the gutter.
Before running the app from the IDE, in a separate terminal:
# From the monorepo root, build the bridge once (or after bridge source changes):
pnpm --filter @contentful/optimization-js-bridge build
# Then start the mock server and leave it running:
pnpm --dir lib/mocks serve
The E2E suite is Maestro, run from the command line rather than an IDE run
configuration — pnpm test:e2e (both apps) or see maestro/README.md.
Use this app when you need a debuggable native Android surface for changes in
packages/android/ContentfulOptimization or the shared JS bridge. The Gradle project includes the
SDK module from the workspace through a composite build, so app builds compile the Kotlin source and
package the local bridge asset rather than a published AAR.
The normal loop is:
Edit Kotlin in packages/android/ContentfulOptimization/src/main/kotlin/... or bridge TypeScript
in packages/universal/optimization-js-bridge/src/....
Build the changed app or both app shells from implementations/android-sdk/:
./gradlew :compose:assembleDebug :views:assembleDebug
Run the Compose or Views app locally, then validate with the matching Maestro flow.
If bridge source changed, rebuild the bridge before treating app results as meaningful:
pnpm --filter @contentful/optimization-js-bridge build
Run the smallest check that covers the changed surface:
| Change area | Suggested validation |
|---|---|
| Bridge TypeScript only | pnpm --filter @contentful/optimization-js-bridge typecheck and pnpm --filter @contentful/optimization-js-bridge build |
| Kotlin SDK or UI adapter behavior | ./gradlew :compose:assembleDebug :views:assembleDebug |
| Compose or Views user flow | pnpm test:e2e:compose -- --flow <suite> or pnpm test:e2e:views -- --flow <suite> |
| Shared preview-panel behavior | Run the affected Maestro suite against both apps |
| Documentation-only README changes | Prettier on touched Markdown and git diff --check |
Common local pitfalls:
http://10.0.2.2:8000; no manual adb reverse setup is
required for normal local runs.