advero_flutter 0.2.0
advero_flutter: ^0.2.0 copied to clipboard
Flutter SDK for publishers to display Advero ads in their apps (Android + iOS). Client-side ad fetching/rendering only.
advero_flutter #
Flutter SDK that publishers embed in their apps (Android + iOS) to display
Advero ads. Talks to the Ad Serving Engine's /ads/* routes
(backend/application/controllers/Ads.php), authenticated by
placementCode — not by cookie/session.
The Dart package name is advero_flutter (snake_case, required by Dart
package naming conventions), while the repo/directory is advero-flutter
(dash, GitHub convention) — same package, just two different naming rules
for two different contexts.
Install #
Via pub.dev (once published) #
dependencies:
advero_flutter: ^0.2.0
Via git dependency (available now, before publishing) #
dependencies:
advero_flutter:
git:
url: https://github.com/cuongcds/advero-flutter.git
Then:
flutter pub get
Usage #
The SDK never assumes or defaults the Advero backend's domain — you must
pass your own baseUrl explicitly. Replace https://ads-advero.domain.com
below with the actual ad-serving endpoint for your Advero account (this is a
placeholder, not a real host).
import 'package:advero_flutter/advero_flutter.dart';
import 'package:flutter/material.dart';
void main() {
AdveroSDK.init(
baseUrl: 'https://ads-advero.domain.com', // your Advero ad-serving endpoint — required, no default
);
runApp(const MyApp());
}
Then drop AdveroAdView anywhere in your widget tree, one per ad slot:
AdveroAdView(
placementCode: 'YOUR_PLACEMENT_CODE', // required, no default
)
Call AdveroSDK.init() once per app (e.g. in main() before runApp()).
Use one AdveroAdView per ad slot — each slot has its own placementCode.
Getting your baseUrl/placementCode #
baseUrlis the ad-serving endpoint for your Advero account — ask whoever manages your Advero account/deployment for this URL; the SDK has no default and will refuse to run without it.placementCodeis a single opaque value (propertyCode-randomCode, e.g.ap-0123456789abcdef01234567-89abcdef) generated for each placement — you copy it as-is, never construct or split it yourself:- Log in to Advero and go to your Property's Placements list
(Properties (
/property) → open your app's Property → Placements). - Next to the placement you want to embed, click the copy icon under Placement code.
- Paste that value as
placementCodeabove. It only works for the property it belongs to — a code copied for one property will not serve ads for another.
- Log in to Advero and go to your Property's Placements list
(Properties (
AdveroSDK.init({ required String baseUrl }) #
| Parameter | Required | Description |
|---|---|---|
baseUrl |
yes | Origin of the Advero ad-serving endpoint, e.g. https://ads-advero.domain.com. Must be supplied by you — the SDK does not hardcode or default to any Advero domain. |
Throws an ArgumentError immediately if baseUrl is missing or empty —
this is a configuration error meant to be caught during integration, not at
runtime in front of real users.
AdveroAdView widget parameters #
| Parameter | Required | Description |
|---|---|---|
placementCode |
yes | The placement's code (propertyCode-randomCode), copied from the Placements list. Must be supplied by you — no default. Throws ArgumentError if empty. |
showPlaceholder |
no | When there's no eligible advertiser creative, the API returns a placeholder ("Advertise here" banner linking to this placement's Marketplace listing) instead of leaving the slot empty. Defaults to true. Pass false to render nothing in that case instead of the placeholder. |
lazy |
no | When true, the ad is only requested once the slot is within ~200 logical pixels of the screen, so ads that are never scrolled to are never served. Defaults to false. |
viewer |
no | Signed signal about the user, produced by your server (see "Viewer signal" below): AdveroViewer(expires: ..., token: ..., age: ..., gender: ...). Omit it when you do not know the user's age or gender. |
onAdLoaded |
no | Called once a real ad (or an allowed placeholder) has been fetched and is about to be shown. |
onEmpty |
no | Called when there is nothing to display (204, network/parse error, or a placeholder suppressed by showPlaceholder: false). |
Behavior #
- On success (
200withcreative_url/click_url), renders the creative as a tappable image (Image.network) — tapping opensclick_urlin an external browser viaurl_launcher. This also covers the placeholder response (placeholder: true) unlessshowPlaceholder: falsewas passed. - Advertiser creatives carry a small Advero icon in the top-right corner (like Google's AdChoices badge), loaded from your
baseUrl(/assets/images/favicons/favicon_white.png). Tapping it opensbaseUrl(the Advero home page) in the external browser; it is a sibling of the creative's tap target, so using it never counts as an ad click. The house placeholder has no badge. - Viewability: every advertiser ad is measured. Once at least 50% of the widget (30% for very large ads) has been visible — not scrolled out or clipped by an ancestor — for 1 continuous second while the app is in the foreground, the SDK POSTs one beacon to the signed
view_urlof the response, and only such viewable impressions are billed for CPM campaigns. The thresholds come from the server response. The house placeholder is never measured. - On
204 No Content, any network error, or a malformed/unparseable response, the widget silently collapses toSizedBox.shrink()— this is normal (no eligible campaign for that placement right now), not a failure, and never throws or surfaces aFlutterError. - Throws only for integration mistakes: missing/empty
placementCodeat construction time, or usingAdveroAdViewbefore callingAdveroSDK.init().
Viewer signal (optional) #
If your app knows the user's age (account profile, age gate) you can pass it so ads are matched to the actual user instead of the placement's declared audience. The signal must be signed on your server with the property's signal secret (Advero dashboard, Property settings, "Signal secret"); never put the secret in the app.
token = HMAC_SHA256_hex( "<placementCode>|<age>|<gender>|<expires>", signalSecret )
age and gender (male / female) are empty strings when omitted, expires is a unix timestamp at most one hour ahead.
AdveroAdView(
placementCode: placementCode,
viewer: AdveroViewer(age: 34, gender: 'female', expires: 1790000000, token: '...'),
)
An unsigned, forged or expired signal is ignored. A signal can only narrow who sees an ad: it never lets adult content onto a placement declared for minors. You are responsible for the accuracy of the signal you send.
Dependencies #
http— official Dart team package, used for the singleGETrequest per ad slot.url_launcher— opensclick_urlin the device's browser/external app on tap.- Images are rendered with Flutter's built-in
Image.network, which already caches through the framework's defaultImageCache— no extra caching dependency is included to keep the dependency footprint minimal. If you need stronger disk caching, swap incached_network_imageyourself.
Example #
A runnable example app lives in example/:
cd example
flutter run
Versioning #
Semver.