
Rapidly integrate Google AdMob ads as composable UI elements—banners, interstitials, rewarded and native; supports preloading, custom native templates, AdState-aware display, consent handling and HTML banners.
A Kotlin Multiplatform library to rapidly get Google AdMob running on Android, iOS and WASM.
[!NOTE] This library is based on Basic-Ads by LexiLabs, extended with additional features including WASM Ads support and improved platform integrations.
Multiads uses the existing Android and iOS Google AdMob libraries to
display ads as Composables.
This library extends the original Basic-Ads with
additional ad types and platform support.
For Android, complete the steps in AdMob's instructions:
For iOS, complete the steps in AdMob's instructions:
[For GDPR Compliance Only] Import the User Messaging Platform SDK
[!NOTE] For Xcode 13+, you can update your Custom iOS Target Properties.
YourProject/
├── composeApp/
│ └── src/
│ └── webMain/
│ └── resources/
│ └── banner.html
with HTML content:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<style>
html, body {
margin: 0;
padding: 0;
}
</style>
<body>
<!--Replase div to your banner-->
<div style="background-color: white; width: 728px; height: 90px; display: flex; align-items: center; justify-content: center;">
<h3>Place for your Banner Ad</h3>
</div>
</body>
</html>Add your dependencies from Maven
# in your 'libs.versions.toml' file
[versions]
multiads = "1.0.6"
[libraries]
multiads = { module = "io.github.mobile-development-group:multiads", version.ref = "multiads" }then include the library in your gradle build
// in your 'composeApp/build.gradle.kts' file
sourceSets {
commonMain.dependencies {
implementation(libs.multiads)
}
}Call Multiads.Initialize in your commonMain before building ads.
// in your 'composeApp/src/commonMain/App.kt' file
@OptIn(DependsOnGoogleMobileAds::class)
@Composable
fun App() {
Multiads.Initialize()
}You can build a BannerAd via a Composable function:
// in your 'composeApp/src/commonMain/AdScreen.kt' file
@Composable
fun AdScreen() {
BannerAd() // Results in a Test Banner Ad being created
}If you want to preload your BannerAds, there's a way to do that too:
// Load the Ad within your Composable
val bannerAd by rememberBannerAd(
data = AdData(
/** adUnitId for Android **/
androidAdUnitId = "ca-app-pub-xxxxx/xxxxx",
/** adUnitId for iOS **/
iOSAdUnitId = "ca-app-pub-xxxxx/xxxxx",
/** HTML banner **/
htmlPage = "banner.html"
),
onLoad = { },
onFailure = { }
)
// Display the Ad as soon as it's available
BannerAd(bannerAd)About HTML banner
You can also check the AdState before doing something:
// Load the Ad within your Composable
val bannerAd by rememberBannerAd()
// Determine to show or hide the Ad
var showBannerAd by remember { mutableStateOf(false) }
// Composable Button with callbacks
Button(
onClick = { showBannerAd = true }, // Shows the ad on click
/** Checks AdState and disables the button if ad isn't ready **/
enabled = bannerAd.value.state == AdState.READY
) { Text("Show Banner Ad") } // label for the button
// Checks for button click
if (showBannerAd) {
// Shows Composable Ad
BannerAd(bannerAd)
}You can also use AdData to configure the banner ad:
val adData = AdData(
androidAdUnitId = "ca-app-pub-xxxxx/xxxxx", // Android Ad Unit ID
iOSAdUnitId = "ca-app-pub-xxxxx/xxxxx", // iOS Ad Unit ID
adSize = AdSize.BANNER,
htmlPage = "banner.html"
)
BannerAd(data = adData)You can also build other Ad types.
// in your 'composeApp/src/commonMain/AdScreen.kt' file
InterstitialAd()
RewardedAd(onRewardEarned = { /** do something here **/ })
RewardedInterstitialAd(onRewardEarned = { /** do something here **/ }) // currently a Google Beta featureIf you want to preload your ads, there's a way to do that too:
// Load the Ad within your Composable
val rewardedAd by rememberRewardedAd()
// Display the Ad as soon as it's available
RewardedAd(
loadedAd = rewardedAd.value,
onRewardEarned = { rewardItem ->
/** do something here with the rewardItem (if it exists) **/
}
)You can also check the AdState before doing something:
// Load the Ad within your Composable
val interstitialAd by rememberInterstitialAd()
// Determine to show or hide the Ad
var showInterstitialAd by remember { mutableStateOf(false) }
// Composable Button with callbacks
Button(
onClick = { showInterstitialAd = true }, // Shows the ad on click
/** Checks AdState and disables the button if ad isn't ready **/
enabled = interstitialAd.value.state == AdState.READY
) { Text("Show Interstitial Ad") } // label for the button
// Checks for button click
if (showInterstitialAd) {
// Shows Composable Ad
InterstitialAd(interstitialAd.value)
}You can build a NativeAd via a Composable function using NativeAdTemplate:
// in your 'composeApp/src/commonMain/AdScreen.kt' file
@Composable
fun AdScreen() {
NativeAd(
data = AdData(
androidAdUnitId = "ca-app-pub-xxxxx/xxxxx",
iOSAdUnitId = "ca-app-pub-xxxxx/xxxxx",
htmlPage = "native.html"
)
)
}For more control, you can preload and manage native ads:
// Load the Ad within your Composable
val nativeAd by rememberNativeAd(
data = AdData(
androidAdUnitId = "ca-app-pub-xxxxx/xxxxx",
iOSAdUnitId = "ca-app-pub-xxxxx/xxxxx",
htmlPage = "native.html"
)
)
// Display the Ad as soon as it's available
NativeAd(
loadedAd = nativeAd.value,
nativeAdTemplate = NativeAdDefault() // or your custom template
)You can create custom native ad templates by extending NativeAdTemplate:
class CustomNativeAdTemplate(
override val nativeAdData: NativeAdData? = null
) : NativeAdTemplate(nativeAdData) {
override fun copy(nativeAdData: NativeAdData?): NativeAdTemplate =
CustomNativeAdTemplate(nativeAdData)
@Composable
override fun Show(modifier: Modifier) {
Supervisor(modifier) {
// Build your custom native ad layout using:
// AdChoices(), Advertiser(), Attribution(), Body(),
// CallToAction(), Headline(), Icon(), Media(),
// Price(), StarRating(), Store(), NativeAdButton()
}
}
}[!TIP] Consent Popups are typically only required for Californian or International audiences. GDPR is a very in-depth topic, so please begin by reading about what GDPR is
and how AdMob complies with GDPR requirements.
You can use the Consent features of Multiads with Composables too:
// in your 'composeApp/src/commonMain/AdScreen.kt' file
// You can also configure debugging using the overload version of this function
// val consent by rememberConsent(debugSettings = ConsentDebugSettings.builder().build())
val consent by rememberConsent()
// Create a ConsentPopup (if available in your region)
ConsentPopup(consent)
// Check if the user can see ads
if (consent.canRequestAds) {
// Call your ads here
InterstitialAd()
}Contributions are welcome! Please feel free to submit a Pull Request.
A Kotlin Multiplatform library to rapidly get Google AdMob running on Android, iOS and WASM.
[!NOTE] This library is based on Basic-Ads by LexiLabs, extended with additional features including WASM Ads support and improved platform integrations.
Multiads uses the existing Android and iOS Google AdMob libraries to
display ads as Composables.
This library extends the original Basic-Ads with
additional ad types and platform support.
For Android, complete the steps in AdMob's instructions:
For iOS, complete the steps in AdMob's instructions:
[For GDPR Compliance Only] Import the User Messaging Platform SDK
[!NOTE] For Xcode 13+, you can update your Custom iOS Target Properties.
YourProject/
├── composeApp/
│ └── src/
│ └── webMain/
│ └── resources/
│ └── banner.html
with HTML content:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<style>
html, body {
margin: 0;
padding: 0;
}
</style>
<body>
<!--Replase div to your banner-->
<div style="background-color: white; width: 728px; height: 90px; display: flex; align-items: center; justify-content: center;">
<h3>Place for your Banner Ad</h3>
</div>
</body>
</html>Add your dependencies from Maven
# in your 'libs.versions.toml' file
[versions]
multiads = "1.0.6"
[libraries]
multiads = { module = "io.github.mobile-development-group:multiads", version.ref = "multiads" }then include the library in your gradle build
// in your 'composeApp/build.gradle.kts' file
sourceSets {
commonMain.dependencies {
implementation(libs.multiads)
}
}Call Multiads.Initialize in your commonMain before building ads.
// in your 'composeApp/src/commonMain/App.kt' file
@OptIn(DependsOnGoogleMobileAds::class)
@Composable
fun App() {
Multiads.Initialize()
}You can build a BannerAd via a Composable function:
// in your 'composeApp/src/commonMain/AdScreen.kt' file
@Composable
fun AdScreen() {
BannerAd() // Results in a Test Banner Ad being created
}If you want to preload your BannerAds, there's a way to do that too:
// Load the Ad within your Composable
val bannerAd by rememberBannerAd(
data = AdData(
/** adUnitId for Android **/
androidAdUnitId = "ca-app-pub-xxxxx/xxxxx",
/** adUnitId for iOS **/
iOSAdUnitId = "ca-app-pub-xxxxx/xxxxx",
/** HTML banner **/
htmlPage = "banner.html"
),
onLoad = { },
onFailure = { }
)
// Display the Ad as soon as it's available
BannerAd(bannerAd)About HTML banner
You can also check the AdState before doing something:
// Load the Ad within your Composable
val bannerAd by rememberBannerAd()
// Determine to show or hide the Ad
var showBannerAd by remember { mutableStateOf(false) }
// Composable Button with callbacks
Button(
onClick = { showBannerAd = true }, // Shows the ad on click
/** Checks AdState and disables the button if ad isn't ready **/
enabled = bannerAd.value.state == AdState.READY
) { Text("Show Banner Ad") } // label for the button
// Checks for button click
if (showBannerAd) {
// Shows Composable Ad
BannerAd(bannerAd)
}You can also use AdData to configure the banner ad:
val adData = AdData(
androidAdUnitId = "ca-app-pub-xxxxx/xxxxx", // Android Ad Unit ID
iOSAdUnitId = "ca-app-pub-xxxxx/xxxxx", // iOS Ad Unit ID
adSize = AdSize.BANNER,
htmlPage = "banner.html"
)
BannerAd(data = adData)You can also build other Ad types.
// in your 'composeApp/src/commonMain/AdScreen.kt' file
InterstitialAd()
RewardedAd(onRewardEarned = { /** do something here **/ })
RewardedInterstitialAd(onRewardEarned = { /** do something here **/ }) // currently a Google Beta featureIf you want to preload your ads, there's a way to do that too:
// Load the Ad within your Composable
val rewardedAd by rememberRewardedAd()
// Display the Ad as soon as it's available
RewardedAd(
loadedAd = rewardedAd.value,
onRewardEarned = { rewardItem ->
/** do something here with the rewardItem (if it exists) **/
}
)You can also check the AdState before doing something:
// Load the Ad within your Composable
val interstitialAd by rememberInterstitialAd()
// Determine to show or hide the Ad
var showInterstitialAd by remember { mutableStateOf(false) }
// Composable Button with callbacks
Button(
onClick = { showInterstitialAd = true }, // Shows the ad on click
/** Checks AdState and disables the button if ad isn't ready **/
enabled = interstitialAd.value.state == AdState.READY
) { Text("Show Interstitial Ad") } // label for the button
// Checks for button click
if (showInterstitialAd) {
// Shows Composable Ad
InterstitialAd(interstitialAd.value)
}You can build a NativeAd via a Composable function using NativeAdTemplate:
// in your 'composeApp/src/commonMain/AdScreen.kt' file
@Composable
fun AdScreen() {
NativeAd(
data = AdData(
androidAdUnitId = "ca-app-pub-xxxxx/xxxxx",
iOSAdUnitId = "ca-app-pub-xxxxx/xxxxx",
htmlPage = "native.html"
)
)
}For more control, you can preload and manage native ads:
// Load the Ad within your Composable
val nativeAd by rememberNativeAd(
data = AdData(
androidAdUnitId = "ca-app-pub-xxxxx/xxxxx",
iOSAdUnitId = "ca-app-pub-xxxxx/xxxxx",
htmlPage = "native.html"
)
)
// Display the Ad as soon as it's available
NativeAd(
loadedAd = nativeAd.value,
nativeAdTemplate = NativeAdDefault() // or your custom template
)You can create custom native ad templates by extending NativeAdTemplate:
class CustomNativeAdTemplate(
override val nativeAdData: NativeAdData? = null
) : NativeAdTemplate(nativeAdData) {
override fun copy(nativeAdData: NativeAdData?): NativeAdTemplate =
CustomNativeAdTemplate(nativeAdData)
@Composable
override fun Show(modifier: Modifier) {
Supervisor(modifier) {
// Build your custom native ad layout using:
// AdChoices(), Advertiser(), Attribution(), Body(),
// CallToAction(), Headline(), Icon(), Media(),
// Price(), StarRating(), Store(), NativeAdButton()
}
}
}[!TIP] Consent Popups are typically only required for Californian or International audiences. GDPR is a very in-depth topic, so please begin by reading about what GDPR is
and how AdMob complies with GDPR requirements.
You can use the Consent features of Multiads with Composables too:
// in your 'composeApp/src/commonMain/AdScreen.kt' file
// You can also configure debugging using the overload version of this function
// val consent by rememberConsent(debugSettings = ConsentDebugSettings.builder().build())
val consent by rememberConsent()
// Create a ConsentPopup (if available in your region)
ConsentPopup(consent)
// Check if the user can see ads
if (consent.canRequestAds) {
// Call your ads here
InterstitialAd()
}Contributions are welcome! Please feel free to submit a Pull Request.