---
metadata:
  - name: generator
    content: Diplodoc Platform v5.57.3
alternate:
  - https://boost.yandex.com/doc/en/ad-monetization/dev/flutter7/app-open-ad.md
  - https://boost.yandex.com/doc/ru/ad-monetization/dev/flutter7/app-open-ad.md
  - href: en/ad-monetization/dev/flutter7/app-open-ad.md
    type: text/markdown
    title: Markdown version
  - href: llms.txt
    type: text/markdown
    title: llms.txt
---
> **Documentation Index:** Fetch the complete configuration index at https://boost.yandex.com/doc/en/llms.txt

<!--
Используется в Boost: boost/en/ad-monetization/dev/flutter
-->

# App open ad

<!-- source: en/ad-monetization/dev/_includes7/app-open-ad.md -->
App open ads are a special ad format for monetizing your app load screens. These ads can be closed at any time and are designed to be served when users bring your app to the foreground, either at launch or when returning to it from the background.
<!-- endsource: en/ad-monetization/dev/_includes7/app-open-ad.md -->

This guide will show how to integrate app open ads into a Flutter app. Besides code samples and instructions, it contains format-specific recommendations and links to additional resources.

<!-- source: en/ad-monetization/dev/_includes7/app-open-ad.md -->
{% note alert %}

App open ads can only be placed in an app with a vertical orientation. For a horizontal orientation, ads won't be served.

{% endnote %}
<!-- endsource: en/ad-monetization/dev/_includes7/app-open-ad.md -->


## Appearance

App Open Ads include a **Go to the app** button, which indicates to users that they're currently in your app and can close the ad.

## Prerequisite {#pre}

<!-- source: en/ad-monetization/dev/_includes7/pre-flutter.md -->
1. Follow the Yandex Mobile Ads Flutter plugin integration steps described under [Quick start](https://boost.yandex.com/doc/en/ad-monetization/dev/flutter7/quick-start.md).
2. Make sure that you have the [latest version of the Yandex Mobile Ads Flutter plugin](https://boost.yandex.com/doc/en/ad-monetization/dev/platforms.md). If you're using mediation, update to the most recent [single build version](https://boost.yandex.com/doc/en/ad-monetization/dev/platforms.md).
<!-- endsource: en/ad-monetization/dev/_includes7/pre-flutter.md -->

### Terms

* **Cold start**: Launching the app when it isn't present in RAM, which creates a new app session.
* **Hot start**: Bringing the app from the background, where it's paused in RAM, into the foreground.

## Implementation {#implement}

1. Create an `AppOpenAdLoader` ad loader and install callback functions for ad loading events.
2. Set up the parameters for loading ads using an `AdRequestConfiguration` object.
3. Load the ad with the `AppOpenAdLoader.loadAd(AdRequestConfiguration)` method.
4. Use the `didChangeAppLifecycleState` method in the `WidgetsBindingObserver` interface to handle app status changes and display app open ads.
5. Install callback functions for events where users interact with your ad.
6. Show the ad by calling `AppOpenAd.show()`.
7. Release the resources.

### Key steps

1. Create an `AppOpenAdLoader` ad loader and register listeners for ad loading events.

    ```dart
    @override
    void initState(){
        super.initState();
        MobileAds.initialize();
        _appOpenAdLoader = _createAppOpenAdLoader();
    }

    late final Future<AppOpenAdLoader> _appOpenAdLoader;
    AppOpenAd? _appOpenAd;

    Future<AppOpenAdLoader> _createAppOpenAdLoader(){
        return AppOpenAdLoader.create(
            onAdLoaded: (AppOpenAd appOpenAd){
                // The ad was loaded successfully. Now you can handle it.
                _appOpenAd = appOpenAd;
            },
            onAdFailedToLoad: (error){
                // Ad failed for to load with error
                // Attempting to load a new ad from the OnAdFailedToLoad event is strongly discouraged.
            },
        );
    }
    ```

2. Set up the parameters for loading ads using an `AdRequestConfiguration` object.

    ```dart
    final _adUnitId = 'demo-appopenad-yandex'; // replace with "R-M-XXXXXX-Y"
    late var _adRequestConfiguration = AdRequestConfiguration(adUnitId: _adUnitId);
    ```

    `adUnitId`: A unique identifier that is issued in the Boost interface and looks like this: R-M-XXXXXX-Y.

    {% note tip %}

    For testing purposes, you can use the demo ad unit ID: "demo-appopenad-yandex". Before publishing your ad, make sure you replace the demo unit ID with a real ad unit ID.

    You can expand the ad request parameters using `AdRequestConfiguration`, by passing user interests, contextual page data, location details, or other data as additional arguments. Adding extra context to ad requests can greatly improve ad relevance. To learn more, see [Ad targeting](https://boost.yandex.com/doc/en/ad-monetization/dev/flutter7/target.md).

    {% endnote %}

3. Load the ad with the `loadAd` method, passing `AdRequestConfiguration` as an argument.

    ```dart
    Future<void> _loadAppOpenAd() async {
        final adLoader = await _appOpenAdLoader;
        await adLoader.loadAd(adRequestConfiguration: _adRequestConfiguration);
    }
    ```

4. Use the `didChangeAppLifecycleState` method in the `WidgetsBindingObserver` interface to handle app status changes and display app open ads.

    ```dart
    @override
    void initState(){
        super.initState();
        // ...
        WidgetsBinding.instance.addObserver(this);
    }

    @override
    void didChangeAppLifecycleState(AppLifecycleState state){
        if (state == AppLifecycleState.resumed){
            _showAdIfAvailable();
        }
    }
    ```

5. Register listeners for events where users interact with your ad.

    ```dart
    static var isAdShowing = false;

    void _setAdEventListener({required AppOpenAd appOpenAd }) {
        appOpenAd.setAdEventListener(
            eventListener: AppOpenAdEventListener(
                onAdShown: (){
                    // Called when an ad is shown.
                    isAdShowing = true;
                },
                onAdFailedToShow: (error){
                    // Called when an ad failed to show.
                    isAdShowing = false;

                    // Clear resources after Ad dismissed.
                    _clearAppOpenAd();
                    // Now you can preload the next ad.
                    _loadAppOpenAd();
                },
                onAdDismissed: (){
                    // Called when an ad is dismissed.
                    isAdShowing = false;

                    // Clear resources.
                    _clearAppOpenAd();
                    // Now you can preload the next ad.
                    _loadAppOpenAd();
                },
                onAdClicked: (){
                    // Called when a click is recorded for an ad.
                },
                onAdImpression: (data){
                    // Called when an impression is recorded for an ad.
                }
            )
        );
    }
    ```

6. Show the ad by calling `AppOpenAd.show()`.

    ```dart
    Future<void> _showAdIfAvailable() async {
        var appOpenAd = _appOpenAd;
        if (appOpenAd != null && !isAdShowing){
            _setAdEventListener(appOpenAd: appOpenAd);
            await appOpenAd.show();
            await appOpenAd.waitForDismiss();
        } else{
            _loadAppOpenAd();
        }
    }
    ```

7. Clear the links for shown ads if you no longer use them. That releases the resources and prevents memory leaks.

    ```dart
    void _clearAppOpenAd() {
        _appOpenAd?.destroy();
        _appOpenAd = null;
    }
    ```

### Full code example

```dart
class _AppOpenAdPageState extends State<AppOpenAdPage> with WidgetsBindingObserver {
    final _adUnitId = 'demo-appopenad-yandex';
    late var _adRequestConfiguration = AdRequestConfiguration(adUnitId: _adUnitId);
    AppOpenAd? _appOpenAd;
    late final Future<AppOpenAdLoader> _appOpenAdLoader = _createAppOpenAdLoader();

    static var isAdShowing = false;
    static var isColdStartAdShown = false;

    Future<AppOpenAdLoader> _createAppOpenAdLoader() {
        return AppOpenAdLoader.create(
            onAdLoaded: (AppOpenAd appOpenAd) {
                // The ad was loaded successfully. Now you can handle it.
                _appOpenAd = appOpenAd;

                if (!isColdStartAdShown) {
                    _showAdIfAvailable();
                    isColdStartAdShown = true;
                }
            },
            onAdFailedToLoad: (error) {
                // Ad failed for to load with error
                // Attempting to load a new ad from the OnAdFailedToLoad event is strongly discouraged.
            },
        );
    }

    @override
    void initState() {
        super.initState();
        MobileAds.initialize();
        _appOpenAdLoader = _createAppOpenAdLoader();
        _loadAppOpenAd();
        WidgetsBinding.instance.addObserver(this);
    }

    Future<void> _loadAppOpenAd() async {
        final adLoader = await _appOpenAdLoader;
        await adLoader.loadAd(adRequestConfiguration: _adRequestConfiguration);
    }

    @override
    void didChangeAppLifecycleState(AppLifecycleState state) {
        if (state == AppLifecycleState.resumed) {
            _showAdIfAvailable();
        }
    }

    void _setAdEventListener({required AppOpenAd appOpenAd }) {
        appOpenAd.setAdEventListener(
            eventListener: AppOpenAdEventListener(
                onAdShown: () {
                    // Called when an ad is shown.
                    isAdShowing = true;
                },
                onAdFailedToShow: (error) {
                    // Called when an ad failed to show.

                    // Clear resources after Ad dismissed.
                    _clearAppOpenAd();
                    // Now you can preload the next ad.
                    _loadAppOpenAd();
                },
                onAdDismissed: () {
                    // Called when an ad is dismissed.
                    isAdShowing = false;

                    // Clear resources.
                    _clearAppOpenAd();
                    // Now you can preload the next ad.
                    _loadAppOpenAd();
                },
                onAdClicked: () {
                    // Called when a click is recorded for an ad.
                },
                onAdImpression: (data) {
                    // Called when an impression is recorded for an ad.
                }
            )
        );
    }

    Future<void> _showAdIfAvailable() async {
        var appOpenAd = _appOpenAd;
        if (appOpenAd != null && !isAdShowing) {
            _setAdEventListener(appOpenAd: appOpenAd);
            await appOpenAd.show();
            await appOpenAd.waitForDismiss();
        } else {
            loadAppOpenAd();
        }
    }

    void _clearAppOpenAd() {
        _appOpenAd?.destroy();
        _appOpenAd = null;
    }
}
```

## Features of app open ad integration {#features}

1. Ads may take a long time to load, so you should avoid increasing the cold start time if the ad hasn't loaded.
2. Preload ads for subsequent hot start impressions in advance.
3. We don't recommend loading app open ads simultaneously with other ad formats at app startup, as the app may be downloading essential operational data. Doing so could lead to excessive loads on your device and internet connection, resulting in longer ad load times.
4. If the `OnAdFailedToLoad` event returns an error, don't try to load a new ad again. If there's no other option, limit the number of ad load retries. This will help avoid constant unsuccessful requests and connection issues if there are limitations.

## Testing App Open Ad integration {#test}

{% list tabs %}

- Android

  <!-- source: en/ad-monetization/dev/_includes7/test-android-app-open-ad.md -->
  ### Using demo ad units for ad testing {#demo-blocks}

  Use test ads to check your App Open Ad integration and the app itself.

  To make sure that test ads are returned for each ad request, we created a special demo ad placement ID designed to help you test your ad integration.

  Demo adUnitId: `demo-appopenad-yandex`.

  {% note warning %}

  Before publishing your app in the store, make sure to replace the demo placement ID with the real ID you obtained in the interface Boost.

  {% endnote %}

  For the list of all available demo ad placement IDs, see [Demo ad units for testing](https://boost.yandex.com/doc/en/ad-monetization/dev/android7/demo-blocks.md).

  ### Testing ad integration {#test-int}

  You can check your integration of app open ads using the SDK's built-in analyzer.

  The tool makes sure your app open ads are integrated properly and outputs a detailed report to the log.
  To view the report, search the keyword “YandexAds” in [Logcat](https://developer.android.com/studio/command-line/logcat), a tool for debugging Android apps.
  ```bash
  adb logcat -v brief '*:S YandexAds'
  ```

  If the integration is successful, the following message is returned:
  ```bash
  adb logcat -v brief '*:S YandexAds'
  mobileads$ adb logcat -v brief '*:S YandexAds'
  I/YandexAds(13719): [Integration] Ad type App Open Ad was integrated successfully
  ```

  If you're having problems integrating ads, you'll get a detailed report on the issues and recommendations for how to fix them.
  <!-- endsource: en/ad-monetization/dev/_includes7/test-android-app-open-ad.md -->

- iOS

  <!-- source: en/ad-monetization/dev/_includes7/test-ios-app-open-ad.md -->
  ### Using demo ad units for ad testing {#demo-blocks}

  Use test ads to check your App Open Ad integration and the app itself.

  To make sure that test ads are returned for each ad request, we created a special demo ad placement ID designed to help you test your ad integration.

  Demo adUnitId: `demo-appopenad-yandex`.

  {% note warning %}

  Before publishing your app in the store, make sure to replace the demo placement ID with the real ID you obtained in the interface Boost.

  {% endnote %}

  For the list of all available demo ad placement IDs, see [Demo ad units for testing](https://boost.yandex.com/doc/en/ad-monetization/dev/ios7/demo-blocks.md).
  <!-- endsource: en/ad-monetization/dev/_includes7/test-ios-app-open-ad.md -->

  ### Testing ad integration

  <!-- source: en/ad-monetization/dev/_includes7/test-integration-ios.md -->
  You can test your ad integration using the native Console tool.

  To view detailed logs, call the `MobileAds` class's `enableLogging` method.

  ```swift
  MobileAds.enableLogging()
  ```

  To view SDK logs, go to the Console tool and set `Subsystem = com.mobile.ads.ads.sdk`. You can also filter logs by category and error level.

  If you're having problems integrating ads, you'll get a detailed report on the issues and recommendations for how to fix them.

  <img src= "https://yastatic.net/s3/doc-binary/src/dev/mobile-ads/common/integration-ios-2.png">
  <!-- endsource: en/ad-monetization/dev/_includes7/test-integration-ios.md -->

{% endlist %}

## Recommendations

1. We don't recommend showing App Open Ads before the app reaches the splash screen.

   Showing the splash screen enhances the user experience, making it more intuitive. This way, the user will know that they opened the right app and won't be surprised or confused by the ad. On this screen, you can also warn users about the upcoming ad. To do this, use a loading indicator or a simple text message informing the user that they can continue viewing the app content after the ad.

2. If there's a delay between requesting and rendering the ad, the user might briefly open your app and then unexpectedly see an ad unrelated to the contents. This can negatively impact the user experience, so it's best to avoid such situations. One solution is to show the splash screen before displaying the main app content and to begin ad impressions from that screen. We don't recommend displaying an ad if the app has already opened content after the splash screen.

3. Wait for new users to open the app and use it a few times before starting to serve App Open Ad impressions. Show the ad only to users who meet specific criteria (for example, if they completed a particular level, opened the app a certain number of times, or don't participate in reward offers). We don't recommend displaying an ad immediately after the app is installed.

4. Adjust the frequency of impressions based on user behavior. We don't recommend serving an ad at every cold or hot app start.

5. Display ads only if the app has been running in the background for a certain time (for example, 30 seconds, 2 minutes, or 15 minutes).

6. Be sure to conduct tests, because each app is unique and requires its own approach to maximize revenue without sacrificing user retention or time spent in the app. User behavior and engagement may change over time, so we recommend periodically testing different display strategies for App Open Ads within your app.

## Additional resources {#resources}

You can view complete integration examples here:

* <!-- source: en/ad-monetization/dev/_includes7/github-pubdev-links.md -->
  Link to [pub.dev](https://pub.dev/packages/yandex_mobileads/example).
  <!-- endsource: en/ad-monetization/dev/_includes7/github-pubdev-links.md -->

* <!-- source: en/ad-monetization/dev/_includes7/github-pubdev-links.md -->
  Link to [GitHub](https://github.com/yandexmobile/yandex-ads-flutter-plugin).
  <!-- endsource: en/ad-monetization/dev/_includes7/github-pubdev-links.md -->
