teads_flutter
Teads video advertising and content recommendations in one Flutter plugin, with a single Dart API for iOS and Android.
| Placement | Dart API | What it is |
|---|---|---|
| Feed | FeedPlacement |
SmartFeed — a self-paginating recommendations feed |
| Media (InRead) | MediaPlacement |
Video/display ad rendered inline in your content |
| Banner | BannerPlacement |
Banner slot, with runtime dark-mode toggling |
| Interstitial | InterstitialPlacement |
Fullscreen ad: preload, then present. Not a widget |
| Recommendations | Recommendations.fetch |
Recommendation data — you build the list UI |
Media Native is not supported.
Documentation: the full guide — installation, every placement, events, privacy and consent, troubleshooting — is at developers.teads.com. The API reference is on pub.flutter-io.cn.
Requirements
| Flutter / Dart | 3.44+ / 3.12+ |
| iOS | deployment target 15.0+, CocoaPods |
| Android | minSdk 24, compileSdk 36, NDK 27.1.12297006+, JDK 17 or 21; Kotlin 2.2.20+, AGP 8.11.1+, Gradle 8.14.3+ |
Installation
flutter pub add teads_flutter
Android
-
Add the Teads Maven repository, in
android/build.gradle(allprojects { repositories { … } }) or inandroid/settings.gradle'sdependencyResolutionManagementif your project centralizes repositories:maven { url "https://teads.jfrog.io/artifactory/SDKAndroid-maven-prod" } -
Declare an AdMob application ID in
AndroidManifest.xml. This is required even if you don't use AdMob: the native SDK depends onplay-services-ads, which crashes at app start without one.<meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="ca-app-pub-3940256099942544~3347511713" /> <!-- Google's sample ID; use your own if you monetize through AdMob --> -
Pin the NDK in
android/app/build.gradle:android { ndkVersion = "27.1.12297006" // or newer }
No ProGuard/R8 rules are needed; the plugin ships its own.
iOS
Set platform :ios, '15.0' in ios/Podfile, then pod install. TeadsSDK is
resolved from the CocoaPods trunk automatically.
To request the IDFA, add a usage description to ios/Runner/Info.plist — without it
iOS denies the request without prompting:
<key>NSUserTrackingUsageDescription</key>
<string>Allows us to show you more relevant ads.</string>
Usage
Configure the SDK once, before creating any placement:
import 'package:flutter/material.dart';
import 'package:teads_flutter/teads_flutter.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await TeadsSdk.configure('YOUR_APP_KEY');
runApp(const MyApp());
}
Then place ads in your widget tree. Placements size themselves — don't wrap them in a fixed-height box.
MediaPlacement(
config: MediaPlacementConfig(
pid: 84242,
articleUrl: 'https://example.com/article/123',
),
onReady: () => debugPrint('Ad ready'),
onFailed: (error) => debugPrint('Failed: ${error.reason}'),
)
FeedPlacement(
config: FeedPlacementConfig(
widgetId: 'MB_1',
installationKey: 'NANOWDGT01',
articleUrl: 'https://example.com/article/123',
),
)
Interstitial is created, loaded and shown imperatively; Recommendations returns data for you to render. See the Integration Guide for every placement.
iOS App Tracking Transparency: call TeadsPrivacy.requestTrackingAuthorization() from
your first screen, not before runApp. On a physical device the prompt's completion
never fires while no UI is on screen, so awaiting it early hangs the app on a white
screen. It returns null on Android, meaning "not applicable".
Things to know
- The widget ID selects the format. Pointing Banner or Interstitial at a Feed
widget ID (such as
MB_1) serves a feed, which looks like a broken placement. - Feed's
widgetIndexis a coordination key, not a position. A placement with awidgetIndexother than0waits for awidgetIndex: 0placement on the same page; if there is none, the ad never loads. Recommendations.registerClickreports the click. Call it when the user actually taps a recommendation, never ahead of time.- Recommendations need an AdChoices icon. Show a clickable AdChoices icon above
your recommendations list that opens
await Recommendations.adChoicesUrl, plus the per-item disclosure icon on paid items. Both are required to ship.Recommendations.setTestRtb(true)forces paid items for testing, and only works withTeadsSdk.setTestMode(true)also set — remove both before release. - Always
dispose()anInterstitialPlacement. It holds a native WebView. - Use one live
BannerPlacementat a time. The native SDK's test-display setting is process-wide, so the most recently created banner wins. - Android emulator can't load the Feed? Emulators often fail to resolve
the feed's asset domain. Boot the emulator with
-dns-server 8.8.8.8,8.8.4.4.
Trying it out
These public test IDs serve demo creatives with no live campaign:
| Placement | widgetId |
installationKey |
articleUrl |
|---|---|---|---|
| Feed | MB_1 |
NANOWDGT01 |
https://mobile-demo.outbrain.com/ |
| Banner | MB_10 |
NANOWDGT01 |
https://mobile-demo.outbrain.com/ |
| Interstitial | INT_MW_1 |
NANOWDGT01 |
https://mobile-demo.outbrain.com |
Media uses pid: 84242; Recommendations uses widget ID SDK_1. The example/ app
wires up every placement with these defaults.
Testing your integration
TeadsSdk, TeadsPrivacy and Recommendations expose injectable interfaces, and
test doubles live in a separate import so they never ship in your production code:
import 'package:teads_flutter/teads_flutter_mocks.dart';
Known limitations
- Media Native is not supported.
- One live
BannerPlacementat a time (see above).
Support
Integration questions go to your Teads Partner Manager; see Support.
License
Apache License 2.0 — see LICENSE and NOTICE. The license covers this plugin's
source only; the native TeadsSDK (iOS) and tv.teads.sdk.android:sdk (Android)
binaries it depends on are distributed separately under their own terms.
Contributing
This plugin is developed by Teads. Teads developers: start from
docs/development.md in the source repository.
Libraries
- teads_flutter
- Flutter SDK for Teads in-app ad formats.
- teads_flutter_mocks
- Test doubles for
package:teads_flutter's injectable interfaces.