Native Ads

Native ads let you monetize your app in a way that’s consistent with its existing design. The AppLovin MAX Flutter plugin v3.0.0 gives you access to an ad’s individual assets so you can design the ad layout to be consistent with the look and feel of your app. The SDK automatically handles image caching and metrics tracking so you can focus on how, when, and where to display ads.

The plugin currently supports only manual integration, such that you can manually load native ad assets into your custom views. This integration method involves three high-level steps:

  1. Declare Flutter UI components.
  2. Refresh the native ad.
  3. Destroy the native ad.

To use the manual API, select the Manual template in the Create New Ad Unit screen:

Template: ☐ Small, ☐ Medium, ☒ Manual

Declare React Native UI Components

The MaxNativeAdView is the container that holds your native ad components. When it mounts, it automatically loads a native ad for the adUnitId attribute you provide.

The plugin provides various components that render various assets of the native ad. You can style these components as you do with other components in your app. As per AppLovin’s policy, your ad must contain the Privacy Information icon. This icon links to an important privacy notice. You can bind to it by using the MaxNativeOptionsView component.

The following table shows the various components that can help you to render native ad assets:

Component Type
MaxNativeAdTitleView Text
MaxNativeAdAdvertiserView Text
MaxNativeAdBodyView Text
MaxNativeAdIconView Container
MaxNativeAdMediaView Container
MaxNativeAdCallToActionView ElevatedButton
MaxNativeAdOptionsView Container
MaxNativeAdStarRatingView Container

The following code sample illustrates a sample native ad that utilizes all of the possible native ad components. AppLovin does not guarantee a network will return certain assets. For a complete working example, see the example app at the AppLovin-MAX-Flutter GitHub project.

Container(
  margin: const EdgeInsets.all(8.0),
  height: 300,
  child: MaxNativeAdView(
    adUnitId: widget.adUnitId,
    controller: _nativeAdViewController,
    listener: NativeAdListener(onAdLoadedCallback: (ad) {
      logStatus('Native ad loaded from ${ad.networkName}');
      setState(() {
        _mediaViewAspectRatio = ad.nativeAd?.Mediacontentaspectratio ?? _kMediaViewAspectRatio;
      });
    }, onAdLoadFailedCallback: (adUnitId, error) {
      logStatus('Native ad failed to load with error code ${error.code} and message: ${error.message}');
    }, onAdClickedCallback: (ad) {
      logStatus('Native ad clicked');
    }, onAdRevenuePaidCallback: (ad) {
      logStatus('Native ad revenue paid: ${ad.revenue}');
    }),
    child: Container(
      color: const Color(0xffefefef),
      padding: const EdgeInsets.all(8.0),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              Container(
                padding: const EdgeInsets.all(4.0),
                child: const MaxNativeAdIconView(
                  width: 48,
                  height: 48,
                ),
              ),
              Flexible(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.start,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    MaxNativeAdTitleView(
                      style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
                      maxLines: 1,
                      overflow: TextOverflow.visible,
                    ),
                    MaxNativeAdAdvertiserView(
                      style: TextStyle(fontWeight: FontWeight.normal, fontSize: 10),
                      maxLines: 1,
                      overflow: TextOverflow.fade,
                    ),
                    MaxNativeAdStarRatingView(
                      size: 10,
                    ),
                  ],
                ),
              ),
              const MaxNativeAdOptionsView(
                width: 20,
                height: 20,
              ),
            ],
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.start,
            children: [
              Flexible(
                child: MaxNativeAdBodyView(
                  style: TextStyle(fontWeight: FontWeight.normal, fontSize: 14),
                  maxLines: 3,
                  overflow: TextOverflow.ellipsis,
                ),
              ),
            ],
          ),
          const SizedBox(height: 8),
          Expanded(
            child: AspectRatio(
              aspectRatio: _mediaViewAspectRatio,
              child: const MaxNativeAdMediaView(),
            ),
          ),
          const SizedBox(
            width: double.infinity,
            child: MaxNativeAdCallToActionView(
              style: ButtonStyle(
                backgroundColor: MaterialStatePropertyAll(Color(0xff2d545e)),
                textStyle: MaterialStatePropertyAll(TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
              ),
            ),
          ),
        ],
      ),
    ),
  ),
),

Ad Reloading

The AppLovin React Native plugin automatically loads the first native ad when the MaxNativeAdView mounts. After it mounts, you can load the next ad by calling the load() method of MaxNativeAdViewController.

final MaxNativeAdViewController _nativeAdViewController = MaxNativeAdViewController();
_nativeAdViewController.loadAd();

Asset Sizes

AppLovin recommends that you incorporate as many of the native elements as appropriate in the context of what the rest of your app looks like, such as the Title and Media View or Icon. Giving the user more information helps them decide whether they want to click on the ad.

For AppLovin Exchange demand, the maximum numbers of characters allowed for Title, Description, and CTA are as follows:

Asset Maximum Character Count
Title 25 characters
Description 100 characters. You can add an ellipsis () after 99 characters, as the 100th character.
CTA 15 characters

For SDK-mediated networks, the maximum limits are set by the network itself.

How to Get the Media Content Aspect Ratio

You can retrieve the Media Content Aspect Ratio for MediaView from adInfo, an argument of the onAdLoaded callback:

ad.nativeAd?mediaContentAspectRatio

Supported Adapter Versions

Ad Network Adapter Version
BidMachine Android 1.9.10.5 / iOS 1.9.5.0.2
Criteo Android 4.8.1.1 / iOS 4.5.0.6
Google Ad Manager Android 22.1.0.1 / iOS 10.3.0.2
Google bidding and Google AdMob Android 22.1.0.1 / iOS 10.3.0.2
InMobi Android 10.1.2.1 / iOS 10.1.1.1
LINE Android 2022.2.16.3 / iOS 2.4.20220630.1
Meta Audience Network Android 6.12.0.1 / iOS 6.12.0.1
Mintegral Android 16.2.61.2 / iOS 7.2.6.0.1
myTarget Android 5.16.0.1 / iOS 5.16.0.1
Pangle Android 4.8.0.8.2 / iOS 4.7.0.8.2
Smaato Android 21.8.5.1 / iOS 21.7.8.1
Yandex Android only 5.3.0.1

Star Rating

You can access and render the star rating for the advertised app. The value, if available, is a floating point number in the range of [0.0, 5.0].

The AppLovin MAX Flutter plugin automatically renders the stars in the MaxNativeAdStarRatingView component. If the network does not provide the star rating, the AppLovin MAX Flutter plugin leaves the star rating component empty. You are responsible for adjusting your layout accordingly.

You can retrieve the star rating for the current ad from ad.nativeAd?starRating.