---
title: "Present onboardings in Flutter SDK"
description: "Learn how to present onboardings effectively to drive more conversions."
---

:::warning
**Onboardings are deprecated in SDK v4 and will be removed in a future release.** They no longer receive fixes or improvements. Use [flows](flutter-get-pb-paywalls) instead: unlike onboardings, which run inside a WebView, flows render natively on the device — giving you smoother animations, a consistent native look and feel, faster load times, and no WebView runtime dependency. See [Get flows & paywalls](flutter-get-pb-paywalls) and [Display flows & paywalls](flutter-present-paywalls) to get started.
:::

If you've customized an onboarding using the builder, you don't need to worry about rendering it in your Flutter app code to display it to the user. Such an onboarding contains both what should be shown within the onboarding and how it should be shown.

Before you start, ensure that:

1. You have installed [Adapty Flutter SDK](sdk-installation-flutter) 3.8.0 or later.
2. You have [created an onboarding](create-onboarding).
3. You have added the onboarding to a [placement](placements).

Adapty Flutter SDK provides two ways to present onboardings:

- **Standalone screen**

- **Embedded widget**

## Present as standalone screen

To display an onboarding as a standalone screen, use the `onboardingView.present()` method on the `onboardingView` created by the `createOnboardingView` method. Each `view` can only be used once. If you need to display the onboarding again, call `createOnboardingView` one more time to create a new `onboardingView` instance.

:::warning
Reusing the same `onboardingView` without recreating it may result in an `AdaptyUIError.viewAlreadyPresented` error.
:::

```dart showLineNumbers title="Flutter"
try {
  await onboardingView.present();
} on AdaptyError catch (e) {
  // handle the error
} catch (e) {
  // handle the error
}
```

### Dismiss the onboarding

When you need to programmatically close the onboarding, use the `dismiss()` method:

```dart showLineNumbers title="Flutter"
try {
  await onboardingView.dismiss();
} on AdaptyError catch (e) {
  // handle the error
} catch (e) {
  // handle the error
}
```

### Configure iOS presentation style

Configure how the onboarding is presented on iOS by passing the `iosPresentationStyle` parameter to the `present()` method. The parameter accepts `AdaptyUIIOSPresentationStyle.fullScreen` (default) or `AdaptyUIIOSPresentationStyle.pageSheet` values.

```dart showLineNumbers
try {
  await onboardingView.present(iosPresentationStyle: AdaptyUIIOSPresentationStyle.pageSheet);
} on AdaptyError catch (e) {
  // handle the error
} catch (e) {
  // handle the error
}
```

## Embed in widget hierarchy

To embed an onboarding within your existing widget tree, use the `AdaptyUIOnboardingPlatformView` widget directly in your Flutter widget hierarchy. 

```dart showLineNumbers title="Flutter"
AdaptyUIOnboardingPlatformView(
  onboarding: onboarding, // The onboarding object you fetched
  onDidFinishLoading: (meta) {
  },
  onDidFailWithError: (error) {
  },
  onCloseAction: (meta, actionId) {
  },
  onPaywallAction: (meta, actionId) {
  },
  onCustomAction: (meta, actionId) {
  },
  onStateUpdatedAction: (meta, elementId, params) {
  },
  onAnalyticsEvent: (meta, event) {
  },
)
```

:::note 
For Android platform view to work, ensure your `MainActivity` extends `FlutterFragmentActivity`:

```kotlin showLineNumbers title="Kotlin"
class MainActivity : FlutterFragmentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }
}
```
:::

## Loader during onboarding

When presenting an onboarding, you may notice a short loading screen between your splash screen and the onboarding while the underlying view is being initialized. You can handle this in different ways depending on your needs.

#### Control splash screen using onDidFinishLoading

:::note
This approach is only available when embedding the onboarding as a widget. It is not available for standalone screen presentation.
:::

The recommended cross-platform approach is to keep your splash screen or custom overlay visible until the onboarding is fully loaded, then hide it manually.

When using the embedded widget, overlay your own widget above it and hide the overlay when `onDidFinishLoading` fires:

```dart showLineNumbers title="Flutter"
AdaptyUIOnboardingPlatformView(
  onboarding: onboarding,
  onDidFinishLoading: (meta) {
    // Hide your custom splash screen or overlay here
  },
  // ... other callbacks
)
```

### Customize native loader

:::important
This approach is platform-specific and requires maintaining native UI code. It's not recommended unless you already maintain separate native layers in your app.
:::

If you need to customize the default loader itself, you can replace it with platform-specific layouts. This approach requires separate implementations for Android and iOS:

- **iOS**: Add `AdaptyOnboardingPlaceholderView.xib` to your Xcode project
- **Android**: Create `adapty_onboarding_placeholder_view.xml` in `res/layout` and define a placeholder there

## Customize how links open in onboardings

:::important
Customizing how links open in onboardings is supported starting from Adapty SDK v3.15.1.
:::

By default, links in onboardings open in an in-app browser. This provides a seamless user experience by displaying web pages within your application, allowing users to view them without switching apps.

If you prefer to open links in an external browser instead, you can customize this behavior by setting the `externalUrlsPresentation` parameter to `AdaptyWebPresentation.externalBrowser`:

<Tabs>
<TabItem value="standalone" label="Standalone screen" default>

```dart showLineNumbers title="Flutter"
final onboardingView = await AdaptyUI().createOnboardingView(
  onboarding: onboarding,
  externalUrlsPresentation: AdaptyWebPresentation.externalBrowser, // default – AdaptyWebPresentation.inAppBrowser
);

try {
  await onboardingView.present();
} on AdaptyError catch (e) {
  // handle the error
} catch (e) {
  // handle the error
}
```

</TabItem>
<TabItem value="embedded" label="Embedded widget">

```dart showLineNumbers title="Flutter"
AdaptyUIOnboardingPlatformView(
  onboarding: onboarding,
  externalUrlsPresentation: AdaptyWebPresentation.externalBrowser, // default – AdaptyWebPresentation.inAppBrowser
  onDidFinishLoading: (meta) {
  },
  onDidFailWithError: (error) {
  },
  onCloseAction: (meta, actionId) {
  },
  onPaywallAction: (meta, actionId) {
  },
  onCustomAction: (meta, actionId) {
  },
  onStateUpdatedAction: (meta, elementId, params) {
  },
  onAnalyticsEvent: (meta, event) {
  },
)
```

</TabItem>
</Tabs>

## Disable safe area paddings (Android)

By default, on Android devices, the onboarding view automatically applies safe area paddings to avoid system UI elements like status bar and navigation bar. However, if you want to disable this behavior and have full control over the layout, you can do so by adding a boolean resource to your app:

1. Go to `android/app/src/main/res/values`. If there is no `bools.xml` file, create it.

2. Add the following resource:

```xml
<resources>
    <bool name="adapty_onboarding_enable_safe_area_paddings">false</bool>
</resources>
```

Note that the changes apply globally for all onboardings in your app.