Skip to main content

Overview

Native ads are customizable ads that blend naturally with your app’s content. You can configure the ad to match your app’s UI using AdropNativeAd and AdropNativeAdView.

Key Features

  • Customizable layout to match app design
  • Provides various elements like headline, body, CTA button, profile, etc.
  • Supports image and HTML creative
  • Custom click handling support
  • Backfill ad support
Use the test unit ID in development: PUBLIC_TEST_UNIT_ID_NATIVE

AdropNativeAd

Constructor

Parameters

Properties

Methods

Call dispose() when the native ad is no longer displayed. Failing to dispose leaks the native WebView and can lead to OOM in feed-style screens.
A disposed AdropNativeAd cannot be reused. To request another ad, create a new AdropNativeAd instance.

AdropNativeAdView

A widget that displays native ads on screen.

Constructor

Parameters

AdropNativeProperties

Content properties of the native ad.

Properties

AdropNativeProfile


Basic Usage


AdropNativeListener

Listener to handle native ad events.

Callbacks

Callback Descriptions


Custom Click Handling

Use useCustomClick when video creative or custom click behavior is needed.
When useCustomClick is true, child widget click events are handled as ad clicks.

Displaying HTML Creative

If the native ad includes HTML creative, you can display it using WebView.
For video native creatives, you must render properties.creative (the HTML payload) through a WebView. Passing properties.asset directly into video_player or any other custom player bypasses the SDK’s video tracking pipeline, so VTR is not measured and onAdVideoStart / onAdVideoEnd never fire. See Video Tracking and VTR.
To use HTML creative, you need to add the webview_flutter package.

Handling Backfill Ads

You can check and handle backfill ads using the isBackfilled property.

AdChoices Position

For backfill native ads, you can choose which corner displays the AdChoices badge. Set preferredAdChoicesPosition in the AdropNativeAd constructor.
This setting is a preferred hint for the backfill network and applies only to backfill native ads — direct ads are not affected. The backfill network may override the position depending on its policy.

Video Tracking and VTR

Adrop measures video metrics for native creatives — including impression-to-completion (VTR), onAdVideoStart, and onAdVideoEnd — only when the video is rendered through the SDK’s media surface. On Flutter, that means rendering the HTML creative (properties.creative) inside a WebView, as shown in Displaying HTML Creative. This applies to the ad’s main media (Media 1). For the other media items of a multi-media creative, see Multi-Media Creatives. The properties.asset field returns a URL pointing to the underlying image or video file. It is exposed as supplementary metadata (for example, for thumbnails or your own analytics); it is not intended to drive playback.
Do not feed the properties.asset URL into a custom video player (video_player, chewie, or any third-party player) for a video native ad. When the SDK’s media surface is bypassed:
  • VTR (Video Through Rate) is not collected for that placement.
  • onAdVideoStart / onAdVideoEnd callbacks never fire.
  • Aggregate video performance for the unit will under-report or report zero.
Click (onAdClicked) and impression (onAdImpression) tracking still work because they are wired to AdropNativeAdView, but the video-specific signals are lost.
For video creatives, follow the WebView + HTML creative pattern:
Bind the WebView inside AdropNativeAdView so that click and impression tracking stay attached to the ad container.
If a placement absolutely requires a custom player and you accept that VTR will not be measured, you can still surface click and impression attribution by keeping the ad bound to AdropNativeAdView. In that case, treat the placement as non-VTR inventory in your internal reporting and avoid mixing it with SDK-measured video performance.

Using Extra Fields

Additional fields defined by publishers can be accessed from the extra map.

Multi-Media Creatives

Requires adrop_ads_flutter 1.16.0 or later. If you use backfill, update the backfill module to 1.16.0 as well.
If a native unit has two or more media items, its creatives contain a file for each media item. properties.extraAssets holds every media item of the ad, keyed by the media ID set in the console. Media 1 is always m1, and the other media items use the IDs shown in Media Size on the Ad Unit detail screen, such as m2 and m3.
  • Media 1 (m1) is the same media as properties.asset and properties.creative. Keep displaying it as before, and draw only the other media items yourself.
  • extraAssets is empty for creatives of units with a single media item and for backfill ads. Display those ads as usual.
  • Look up media items by ID instead of relying on their order.
  • If the ad is served in dark mode, image media items are dark mode images too.
  • To check your layout with a multi-media creative, preview the creative on a test device.

AdropNativeAsset

Displaying Media Items

  • Image: With either useCustomClick setting, a tap on a widget inside AdropNativeAdView is an ad click, so a tap on an image you place there is counted like the rest of the ad. Don’t load the creative HTML of an image: it doesn’t report clicks to Adrop.
  • Video: Play the creative HTML, not the asset URL. The HTML contains the video player and its tracking, so video metrics are measured only through it. Place the WebViewWidget outside AdropNativeAdView: inside, every tap, including taps on the player’s controls, becomes an ad click. Load the HTML when the ad is about to appear on screen, not in advance.
  • Landing page: When a user taps the video, its HTML reports the click and asks to open the landing page in a new window or in the same window. Both requests arrive in onNavigationRequest, so open the requested URL there.

Impressions and Clicks

Impressions, clicks, and video metrics are counted once per ad, not per media item, even when both the SDK and a media item report them.
Which taps on a video count as clicks depends on the unit’s video controller setting. With the controller off, every tap on the video is a click. With it on, taps on the play and mute controls aren’t clicks.

Example

This example shows Media 2 (m2) as an image inside AdropNativeAdView, or as a video right below it. Replace m2 with the ID of your unit’s media item. Add the WebView and URL launcher packages first.

Error Handling

When backfill ads are configured, the backfillNoFill error code is returned when both direct ads and backfill ads are unavailable.

General Error Handling


Best Practices

1. Recreating Ads

To load a new ad, create a new AdropNativeAd instance.

2. Conditional Rendering

Display an appropriate placeholder until the ad loads.

3. Responsive Layout

Configure layout to adapt to various screen sizes.

4. Null Check for Ad Properties

Native ad properties can be null, so always check them.

Preloading Backfill Ads (preload)

Starting with SDK 1.17.0, you can use AdropNativeAd.preload() to preload a backfill native ad. When a native ad that you load() with the same unit ID and the same AdChoices position gets no direct ad and falls back to a backfill ad, it uses the preloaded ad right away instead of requesting a backfill ad again. load() still requests a direct ad first, regardless of preload. If a direct ad is received, the preloaded ad is kept as is. If you don’t call preload, the behavior is the same as before.

Requirements

  • You need adrop_ads_flutter 1.17.0 or later and, on the native platforms, the backfill dependency 1.17.0 or later. See Getting Started.
  • Preload fetches a backfill ad only when the server has told the app that there are no direct ads to show right now. Otherwise, it ends with ERROR_CODE_AD_PRELOAD_SKIPPED without requesting a backfill ad. This is a normal result in apps that have direct ad campaigns.
  • Right after the app is installed, right after you change the App Key, and right after you switch to a different user with setUID, preload ends with ERROR_CODE_AD_PRELOAD_SKIPPED until the server response arrives.
  • With test unit IDs, preload always ends with ERROR_CODE_AD_PRELOAD_SKIPPED.

Usage

Call preload right before you open the screen that contains the native ad. A preloaded ad is discarded after 30 minutes if it isn’t used, so call preload only for ads you’re about to display. You don’t need to wait for the result before calling load(). If the ad is still being fetched, load() waits for that result and uses it. preload() completes when preloading succeeds. Any other result (including ERROR_CODE_AD_PRELOAD_SKIPPED) is delivered as a PlatformException whose code is the error code string. If you don’t handle it, even SKIPPED, which is a normal result, is reported as an unhandled asynchronous error, so wrap the call in try/catch or attach .catchError.
If you don’t need the result, you can call it like this.
To use the preloaded ad, create the AdropNativeAd you load() with the same preferredAdChoicesPosition you passed to preload. Both default to AdropAdChoicesPosition.topRight.

When a Preloaded Ad Is Used

  • Same unit ID and same AdChoices position: The AdChoices position is fixed when the backfill ad is fetched, so the preferredAdChoicesPosition of the ad you load() must match the value you passed to preload. If it differs, the preloaded ad is kept as is, and load() requests a backfill ad as usual.
  • Used only once: A preloaded ad is gone once a single load() uses it. To preload again, call preload again.
  • Lifetime and count: An ad that isn’t used within 30 minutes is discarded. Only 1 ad is kept per unit and AdChoices position, and native ads keep up to 5 different combinations. When there are more than 5, ads are discarded starting with the one received first.
  • Calling again: Calling preload again with the same unit and AdChoices position doesn’t make a new request. If an ad has already been preloaded, the call completes without a new request; if one is still being fetched, the call gets that load’s result (success or failure). You can’t use preload to refresh an ad. However, if the user consent status has changed in the meantime, the existing ad is discarded and a new one is fetched.
  • Consent status changes: If the user consent status changes after an ad is preloaded, that ad isn’t used by load().
  • What completion means: When preload() completes, it means preloading has finished. A load() that was waiting for that result may have already used the ad.

Failure Codes

Don’t call preload again right away inside catch. If the result doesn’t change — for example, when the backfill dependency is missing — the calls repeat endlessly. Call it again later, such as before you open the next screen.

Next Steps

Interstitial Ads

Implement full-screen interstitial ads

Rewarded Ads

Implement rewarded ads that provide rewards

Popup Ads

Implement popup-style ads

Reference

Reference types, methods, and error codes