Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions content/docs/android/changelog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,23 @@ title: "Changelog"
description: "Release notes for the Superwall Android SDK"
---

## 2.7.8

### Fixes

- Fix serialization issue with R8 and dates
Comment on lines +6 to +10

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Replace Android 2.7.8/2.7.7 notes with upstream text

content/docs/android/changelog.mdx now lists 2.7.8/2.7.7 changes that differ from the upstream release notes referenced by this update (for example, 2.7.8 is missing the getEntitlements()/dependency notes and 2.7.7 is missing the ProGuard JsonDataException fix), so readers can make upgrade decisions based on incorrect information. This also violates the repository rule in AGENTS.md that SDK changelog entries must be copied verbatim from reference/<sdk>/CHANGELOG.md.

Useful? React with 👍 / 👎.

- Fix scope cancellation for test mode

## 2.7.7

### Enhancements

- Adds support for local resource loading in paywalls via `Superwall.instance.localResources`

### Fixes

- Fix issues with stripe period types failing to deserialize

## 2.7.6

### Fixes
Expand Down
6 changes: 6 additions & 0 deletions content/docs/android/guides/local-resources.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
title: "Local Resources"
description: "Bundle images, videos, and other assets in your app so paywalls can load them instantly from the device."
---

<include>../../../shared/local-resources.mdx</include>
2 changes: 1 addition & 1 deletion content/docs/android/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,4 @@ If you have feedback on any of our docs, please leave a rating and message at th

If you have any issues with the SDK, please [open an issue on GitHub](https://github.com/superwall/superwall-android/issues).

<SdkLatestVersion version="2.7.6" repoUrl="https://github.com/superwall/Superwall-Android" />
<SdkLatestVersion version="2.7.8" repoUrl="https://github.com/superwall/Superwall-Android" />
2 changes: 2 additions & 0 deletions content/docs/android/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"sdk-reference/identify",
"sdk-reference/setUserAttributes",
"sdk-reference/userId",
"sdk-reference/localResources",
"sdk-reference/subscriptionStatus",
"sdk-reference/handleDeepLink",
"sdk-reference/getPresentationResult",
Expand All @@ -46,6 +47,7 @@
"guides/vibe-coding",
"guides/using-revenuecat",
"guides/experimental-flags",
"guides/local-resources",
"guides/advanced",
"guides/migrations",
"[Troubleshooting](https://support.superwall.com/articles/3578026824-troubleshooting-android-sdk)",
Expand Down
6 changes: 3 additions & 3 deletions content/docs/android/quickstart/install.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ can find the [latest release here](https://github.com/superwall/Superwall-Androi
<CodeGroup>

```gradle build.gradle
implementation "com.superwall.sdk:superwall-android:2.7.6"
implementation "com.superwall.sdk:superwall-android:2.7.8"
```

```kotlin build.gradle.kts
implementation("com.superwall.sdk:superwall-android:2.7.6")
implementation("com.superwall.sdk:superwall-android:2.7.8")
```

```toml libs.version.toml
[libraries]
superwall-android = { group = "com.superwall.sdk", name = "superwall-android", version = "2.7.6" }
superwall-android = { group = "com.superwall.sdk", name = "superwall-android", version = "2.7.8" }

// And in your build.gradle.kts
dependencies {
Expand Down
2 changes: 1 addition & 1 deletion content/docs/android/sdk-reference/Superwall.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -177,4 +177,4 @@ Superwall.getInstance().register("feature_access", () -> {

// Set user identity
Superwall.getInstance().identify("user123");
```
```
2 changes: 1 addition & 1 deletion content/docs/android/sdk-reference/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ If you have feedback on any of our docs, please leave a rating and message at th

If you have any issues with the SDK, please [open an issue on GitHub](https://github.com/superwall/superwall-android/issues).

<SdkLatestVersion version="2.7.6" repoUrl="https://github.com/superwall/Superwall-Android" />
<SdkLatestVersion version="2.7.8" repoUrl="https://github.com/superwall/Superwall-Android" />
65 changes: 65 additions & 0 deletions content/docs/android/sdk-reference/localResources.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
title: "localResources"
description: "Register Android resources or file URIs so paywalls can load local media by resource ID."
---

<Info>
Available in Android SDK `2.7.7+`.
</Info>

## Purpose

`localResources` lets you map paywall asset IDs to local Android resources or file URIs. Paywalls can then request those assets with `swlocal://resource-id` instead of downloading them from a remote URL.

## Signature

```kotlin
var localResources: Map<String, PaywallResource>
```

```java
public Map<String, PaywallResource> getLocalResources()
public void setLocalResources(Map<String, PaywallResource> localResources)
```

## Schema

<TypeTable
type={{
key: {
type: "String",
description: "The resource ID used in the paywall editor or in a `swlocal://resource-id` URL.",
required: true,
},
value: {
type: "PaywallResource",
description: "The local Android asset to serve for that resource ID.",
required: true,
},
}}
/>

## PaywallResource variants

<TypeTable
type={{
"PaywallResource.FromResources(resId)": {
type: "Int",
description: "Use an Android resource ID from `res/drawable`, `res/raw`, or another packaged resource folder.",
required: true,
},
"PaywallResource.FromUri(uri)": {
type: "Uri",
description: "Use a local `Uri`, such as a file in app storage or a content provider URL.",
required: true,
},
}}
/>

## Returns / State

This is a mutable property on [`Superwall.instance`](/android/sdk-reference/Superwall). Set it before presenting paywalls that depend on local assets.

## Related

- [Local Resources guide](/android/guides/local-resources)
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,16 @@ description: "Use images, videos, and other media bundled in your app for faster
Local resources let you reference media files (such as images and videos) that are bundled directly in your app rather than hosted on a remote server. This means faster load times, no network dependency for those assets, and a smoother experience for your users.

<Note>
Local resources require **iOS SDK v4.13.0+** or **Android SDK v2.5.0+**. They are not available on
Local resources require **iOS SDK v4.13.0+** or **Android SDK v2.7.7+**. They are not available on
other platforms at this time.
</Note>

### How it works

Instead of pointing an image or video to a URL, you can point it to a **local resource ID**. This ID maps to a file that the developer has registered in the native SDK. When the paywall loads, the SDK intercepts the request and serves the file directly from the device. No network call is required.

Set up those resource IDs in your app first by following the [SDK Local Resources guide](/sdk/guides/local-resources).
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dashboard links to nonexistent /sdk/ doc path

Medium Severity

The previously working link /ios/guides/local-resources was changed to /sdk/guides/local-resources, but no sdk directory exists under content/docs/. Based on the normalizeDocsInternalHref function, this resolves to /docs/sdk/guides/local-resources, which is a nonexistent page. This dashboard page isn't under an SDK-specific path, so no SDK-aware path rewriting applies. These links will be broken for users.

Additional Locations (2)
Fix in Cursor Fix in Web


The editor discovers which resource IDs are available by looking at device attribute events your app has reported in the last 7 days. This means at least one device running your app with the SDK configured must have reported its local resources before they appear in the editor.

### Setting a local resource on an image
Expand Down Expand Up @@ -46,7 +48,7 @@ This means you can safely set a local resource without breaking the paywall for

The resource ID dropdown is populated from device attribute events sent by your app. If you don't see any resource IDs:

- Make sure at least one test device is running your app with the local resources configured in the SDK (see the [iOS guide](/ios/guides/local-resources) for setup instructions).
- Make sure at least one test device is running your app with the local resources configured in the SDK. For setup instructions, see the [SDK Local Resources guide](/sdk/guides/local-resources).
- The device must have opened a paywall or otherwise triggered a device attributes event within the **last 7 days**.
- Only **iOS** and **Android** platforms support local resources. The dropdown will not appear for other platforms.

Expand All @@ -68,6 +70,6 @@ For smaller or frequently changing images, remote URLs are still the simpler cho

### Related

- [iOS SDK: Local Resources Guide](/ios/guides/local-resources): How to register local resources in the iOS SDK.
- [SDK Local Resources Guide](/sdk/guides/local-resources): How to register local resources in supported SDKs.
- [Styling Elements](/paywall-editor-styling-elements): General component styling and image editing.
- [Liquid inside Image URLs](/paywall-editor-liquid#liquid-inside-image-urls): Using dynamic URLs for images.
81 changes: 1 addition & 80 deletions content/docs/ios/guides/local-resources.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,83 +3,4 @@ title: "Local Resources"
description: "Bundle images, videos, and other media in your app for use in paywalls, enabling faster load times and offline support."
---

Local resources allow you to register media files bundled in your app (images, videos, audio) so that paywalls can reference them by ID instead of loading them from a remote URL. The SDK serves these files directly from disk, which means instant loading and no network dependency.

<Note>
Local resources require **iOS SDK v4.13.0+**. Make sure you're on a compatible version before
using this feature.
</Note>

## Registering local resources

Set the `localResources` property on `SuperwallOptions` **before** calling `configure()`. Each entry maps a **resource ID** (a string you choose) to a local file URL:

```swift Swift
let options = SuperwallOptions()
options.localResources = [
"hero-image": Bundle.main.url(forResource: "hero", withExtension: "png")!,
"onboarding-video": Bundle.main.url(forResource: "onboarding", withExtension: "mp4")!
]

Superwall.configure(apiKey: "pk_your_api_key", options: options)
```

The resource IDs you choose here are the same IDs you'll select in the [paywall editor](/dashboard/dashboard-creating-paywalls/paywall-editor-local-resources) when configuring an image or video component.

<Warning>
Local resources must be set **before** calling `configure()`. Resources added after configuration
will not be available for paywalls that have already loaded.
</Warning>

## Supported file types

The SDK supports a wide range of media formats:

| Category | Formats |
| -------- | ------- |
| Images | PNG, JPEG, GIF, WebP, SVG, HEIC, HEIF, AVIF, BMP, TIFF |
| Videos | MP4, MOV, WebM, AVI, HEVC/H.265 |

## Choosing resource IDs

Resource IDs are simple strings that act as the key between your app and the paywall editor. A few tips:

- **Use descriptive names** like `"hero-image"` or `"onboarding-video"` rather than `"img1"`.
- **Keep them stable.** If you change a resource ID, you'll need to update any paywalls that reference it in the editor.
- **They're case-sensitive.** `"Hero-Image"` and `"hero-image"` are different IDs.

## Fallback behavior

In the paywall editor, you can set both a local resource and a remote URL on the same image or video component. If the local file can't be loaded (for example, the resource ID isn't registered or the file is missing from the bundle), the paywall automatically falls back to the remote URL. This ensures paywalls still work on older SDK versions or if a resource is accidentally removed from the app bundle.

## Debugging

The SDK includes a built-in debug view for verifying your local resources are set up correctly. It shows each registered resource ID, its file path, and a preview of the content.

<Tip>
If a resource isn't showing up in the paywall editor dropdown, make sure your test device has
opened a paywall (or otherwise triggered a device attributes event) after configuring
`localResources`. The editor only shows resource IDs reported in the last 7 days.
</Tip>

## Example: Onboarding paywall with a bundled video

A common use case is bundling an onboarding video so it loads instantly the first time a user sees your paywall:

```swift Swift
// In your app's initialization
let options = SuperwallOptions()
options.localResources = [
"onboarding-video": Bundle.main.url(forResource: "welcome", withExtension: "mp4")!,
"app-logo": Bundle.main.url(forResource: "logo", withExtension: "png")!
]

Superwall.configure(apiKey: "pk_your_api_key", options: options)
```

Then in the paywall editor, select "onboarding-video" as the local resource for your video component and "app-logo" for the logo image. Set remote URLs as fallbacks for both.

## Related

- [`SuperwallOptions`](/ios/sdk-reference/SuperwallOptions): Full configuration reference.
- [Paywall Editor: Local Resources](/dashboard/dashboard-creating-paywalls/paywall-editor-local-resources): How to use local resources in the paywall editor.
<include>../../../shared/local-resources.mdx</include>
1 change: 1 addition & 0 deletions content/docs/ios/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"sdk-reference/PurchaseController",
"sdk-reference/SuperwallEvent",
"sdk-reference/SuperwallOptions",
"sdk-reference/localResources",
"sdk-reference/PaywallOptions",
"sdk-reference/advanced",

Expand Down
22 changes: 2 additions & 20 deletions content/docs/ios/sdk-reference/SuperwallOptions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public final class SuperwallOptions: NSObject {
localResources: {
type: "[String: URL]",
description:
"A dictionary mapping resource IDs to local file URLs. Paywalls can reference these IDs to load images, videos, and other media directly from the app bundle instead of a remote URL. Must be set before calling `configure()`. See the [Local Resources guide](/ios/guides/local-resources) for details. Available in version 4.13.0+.",
"A dictionary mapping resource IDs to local file URLs. See [`localResources`](/ios/sdk-reference/localResources) for the property schema and the [Local Resources guide](/ios/guides/local-resources) for setup details.",
default: "[:]",
},
}}
Expand Down Expand Up @@ -191,28 +191,10 @@ func configureSuperwallForDebug() {
}
```

Local resources configuration:

```swift
let options = SuperwallOptions()

// Register bundled media for use in paywalls
options.localResources = [
"hero-image": Bundle.main.url(forResource: "hero", withExtension: "png")!,
"onboarding-video": Bundle.main.url(forResource: "onboarding", withExtension: "mp4")!
]

Superwall.configure(
apiKey: "pk_your_api_key",
options: options
)
```

See the [Local Resources guide](/ios/guides/local-resources) for a full walkthrough.

## Related

- [`PaywallOptions`](/ios/sdk-reference/PaywallOptions)
- [`localResources`](/ios/sdk-reference/localResources)

## Runtime Interface Style Configuration

Expand Down
43 changes: 43 additions & 0 deletions content/docs/ios/sdk-reference/localResources.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
title: "localResources"
description: "Register local file URLs so paywalls can load bundled media by resource ID."
---

<Info>
Available in iOS SDK `4.13.0+`.
</Info>

## Purpose

`localResources` maps resource IDs to local file URLs so paywalls can request bundled media with `swlocal://resource-id` instead of downloading them from a remote URL.

## Signature

```swift
public var localResources: [String: URL]
```

## Schema

<TypeTable
type={{
key: {
type: "String",
description: "The resource ID used in the paywall editor or in a `swlocal://resource-id` URL.",
required: true,
},
value: {
type: "URL",
description: "A local file URL from your app bundle or sandbox.",
required: true,
},
}}
/>

## Returns / State

This is a mutable property on [`SuperwallOptions`](/ios/sdk-reference/SuperwallOptions). Set it before calling [`configure()`](/ios/sdk-reference/configure).

## Related

- [Local Resources guide](/ios/guides/local-resources)
Loading
Loading