diff --git a/guides/ways-to-show-paywall.mdx b/guides/ways-to-show-paywall.mdx
index 0f7b6e0..6a8f582 100644
--- a/guides/ways-to-show-paywall.mdx
+++ b/guides/ways-to-show-paywall.mdx
@@ -26,7 +26,7 @@ HeliumPaywall(
```swift
- HeliumPaywallView(
+ HeliumPaywall(
trigger: "post_onboarding",
eventHandlers: PaywallEventHandlers()
.onOpen { event in
@@ -51,6 +51,48 @@ HeliumPaywall(
```
+
+ `customPaywallTraits` are captured when the paywall **displays** and then stay fixed for that
+ presentation. In SwiftUI this is handled for you as long as the traits come from state that
+ re-renders the view — the normal way you'd pass dynamic values into a view.
+
+ When you host `HeliumPaywall` in UIKit with a `UIHostingController`, UIKit won't refresh the view
+ for you. If you build the hosting controller ahead of time and update traits before showing it,
+ drive the view from an `ObservableObject` so the latest traits reach the paywall before display:
+
+ ```swift
+ final class PaywallTraitsStore: ObservableObject {
+ @Published var traits: HeliumUserTraits?
+ }
+
+ struct PaywallHost: View {
+ @ObservedObject var store: PaywallTraitsStore
+ let trigger: String
+ var body: some View {
+ HeliumPaywall(
+ trigger: trigger,
+ config: PaywallPresentationConfig(customPaywallTraits: store.traits)
+ ) { paywallNotShownReason in
+ Text("Paywall failed to show")
+ }
+ }
+ }
+
+ // UIKit
+ let store = PaywallTraitsStore()
+ store.traits = initialTraits
+ let vc = UIHostingController(rootView: PaywallHost(store: store, trigger: "onboarding"))
+
+ // Later, before the paywall is displayed:
+ store.traits = freshTraits // reaches the paywall via the refreshed config
+ ```
+
+
+ This applies before the paywall is on screen. Once displayed, traits are locked for that
+ presentation — updating the store afterward won't change an already-shown paywall.
+
+
+
#### SwiftUI ViewModifier
Attach a paywall to any SwiftUI view using the **`.heliumPaywall`** view modifier:
diff --git a/sdk/quickstart-ios.mdx b/sdk/quickstart-ios.mdx
index fc879f0..0c8c35f 100644
--- a/sdk/quickstart-ios.mdx
+++ b/sdk/quickstart-ios.mdx
@@ -466,10 +466,10 @@ Helium.identify.revenueCatAppUserId = Purchases.shared.appUserID
You can also create a custom delegate and implement your own purchase logic. You can look at our [StoreKitDelegate](https://github.com/cloudcaptainai/helium-swift/blob/main/Sources/Helium/HeliumCore/StoreKitDelegate.swift) and [RevenueCatDelegate](https://github.com/cloudcaptainai/helium-swift/blob/main/Sources/HeliumRevenueCat/HeliumRevenueCat.swift) in the SDK for examples (also linked below).
-The `HeliumPurchaseDelegate` is defined as follows:
+The `HeliumPaywallDelegate` is defined as follows:
```swift
-public protocol HeliumPurchaseDelegate: AnyObject {
+public protocol HeliumPaywallDelegate: AnyObject {
// Execute the purchase of a product given the product ID.
func makePurchase(productId: String) async -> HeliumPaywallTransactionStatus