> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tryhelium.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Ways to Show a Paywall

> Advanced and alternative ways to present Helium paywalls beyond the standard present method.

## Overview

Most of the time you'll want to use `presentPaywall()` (or `presentUpsell()` depending on your SDK version) to show paywalls. This approach is covered in each platform's quickstart guide (see navigation menu on the left). But if you need more control over how and where paywalls appear in your app, there are a few other options.

## iOS

#### Embedded View

```swift theme={null}
HeliumPaywall(
    trigger: "onboarding"
) { paywallNotShownReason in
    Text("Paywall failed to show")
}
```

<Warning>
  The iOS SDK will attempt to handle dismissal for embedded views but may not be able to depending on where you place it. You can dismissal yourself with PaywallEventHandlers.
</Warning>

<Accordion title="Example with PaywallEventHandlers">
  ```swift theme={null}
  HeliumPaywallView(
      trigger: "post_onboarding",
      eventHandlers: PaywallEventHandlers()
          .onOpen { event in
              print("open for trigger \(event.triggerName)")
          }
          .onClose { event in
              print("close for trigger \(event.triggerName)")
          }
          .onDismissed { event in
              // handle user dismissal here (i.e. navigate to another screen)
              print("dismiss for trigger \(event.triggerName)")
          }
          .onPurchaseSucceeded { event in
              print("purchase made for trigger \(event.triggerName)")
          }
          .onCustomPaywallAction { event in
              print("Custom action: \(event.actionName) with params: \(event.params)")
          }
  ) { paywallNotShownReason in
      Text("Paywall failed to show")
  }
  ```
</Accordion>

#### SwiftUI ViewModifier

Attach a paywall to any SwiftUI view using the **`.heliumPaywall`** view modifier:

```swift theme={null}
struct ContentView: View {
    @State var isPresented: Bool = false
    var body: some View {
        VStack {
            Button {
                isPresented = true
            } label: {
                Text("Show paywall")
            }
        }.heliumPaywall(
            isPresented: $isPresented,
            trigger: "post_onboarding") { paywallNotShownReason in
                Text("Paywall failed to show")
            }
    }
}
```

<Note>
  If you are using UIKit, you can use a UIHostingController.
</Note>

## Android

#### Embedded Paywall (Compose)

<Note>
  Make sure to add `com.tryhelium.paywall:compose-ui:4.0.0` to your dependencies.
</Note>

```kotlin theme={null}
HeliumPaywall(
    trigger = "onboarding",
    onPaywallNotShown = { reason ->
        Text("Paywall failed to show")
    }
)
```

## Flutter

#### Widget Integration

<Warning>
  Flutter embedded widget currently only works for iOS. Android support is in the works.
</Warning>

Embed a paywall directly in your widget tree using **`HeliumFlutter.getUpsellWidget`**:

```dart theme={null}
class ExamplePageWithEmbeddedPaywall extends StatelessWidget {
  const ExamplePageWithEmbeddedPaywall({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: HeliumPaywall(
        trigger: "insert-trigger-here",
        paywallNotShownBuilder: (context, reason) => Text("Paywall failed to show"),
      ),
    );
  }
}
```

<Warning>
  You will have to handle your own dismissal. You can do so by passing in PaywallEventHandlers and using the `onDismissed` handler.
</Warning>
