Advanced Paywall Creation

The following is only necessary if you're looking to build your own website to use as a paywall. We recommend using our templates instead.

Data Tags

Data tags are specific attributes attached to elements, like text, links, or buttons, on the paywall webpage.
These are recognised by a special script called Paywall.js that interprets user feedback and transmits information to and from the SDK. These are built in to the templates we've created and you don't need to worry about them unless you're building your own paywall webpage. When you configure your paywall webpage on the Superwall dashboard, the dashboard instantly recognizes the data tags on your website. From there you can edit the text that appears in the tagged elements.

There are seven different types of data tag:

data-pw-varThe reference name of the element, e.g. "Title".This indicates to Superwall that the element should be remotely configurable. The Superwall dashboard will create an editable text field for this element. The reference name of that text field will be equal to the value you provide.
data-pw-closeAdd anything as a value. It's ignored.Closes the paywall.
data-pw-restoreAdd anything as a value. It's ignored.For restoring purchases, if you bought on a different device.
data-pw-purchaseEither primary, secondary, or tertiary.This relates to your primary, secondary, or tertiary product set up in the Superwall dashboard respectively. When the tagged element is tapped, it tells the SDK to initialize a purchase of the specified product.
data-pw-open-urlA valid url. E.g. <>.Normal href links do not work in a paywall. However, attaching this tag to an element opens the provided url.
data-pw-open-deep-linkA valid deep link url. E.g. fb://profile/33138223345.Opens a deeplink from a button on a paywall.
data-pw-customA name for a custom actionWhen the tagged element is tapped, the SDK calls its delegate method handleCustomPaywallAction(withName:). The value you provide is passed to the function, from which you can perform custom logic. Check out Custom Paywall Buttons for more.
data-pw-skip-inner-htmltrueThis prevents an element's text from being edited. It tells Paywall.js to keep looking into the element's children for more data-pw-var tags. This is useful when you want to hide a whole section or edit the style of a container, rather than edit its text.

Here are a few examples of what data tags look like in the webpage HTML:

<! –– A data tag specifying a templatable title.  ––>
<h1 data-pw-var="title"></h1>

<! –– A data tag specifying that the element should dismiss the paywall ––>
<div data-pw-close="anything"></div>

<! –– Same as above ––>
<div data-pw-close></div>


Paywall.js is a javascript utility that recognizes data tags and acts as the interface between the Superwall client SDK and the webpage presented to the user. It does a few fancy tricks to make the HTML feel native, but it's main purpose is to interpret user feedback and transmit information to and from the SDK. In addition, when you configure a paywall on the Superwall dashboard, the dashboard instantly recognizes the data tags you’ve provided. From there, you can edit the text of all tagged items.

To get your webpage to be operable with Superwall, you need to add the Paywall.js script to the header of your site.

We recommend using Webflow. To add custom scripts to a Webflow webpage you need to have a paid Webflow account. However, our clonable Webflow project already includes this script. Therefore, we recommend using the cloned project as the basis of your paywalls. In this project, we've also removed the Webflow watermark that is attached to all free Webflow webpages.

If you'd like to add this script yourself, open the Pages panel, select the cog wheel next to the page name, then scroll down to the Custom Code section. In the Inside head tag section, add the following code:

<script async src=""></script>


Do not remove async

Paywall.js is available to Superwall customers subject to the terms of the subscription agreement between Superwall and the customer, and is not available as an open-source project.

Game Controller

Paywall.js now supports game controller input so users can make purchases while maintaining the native game controller experience.

Basic Setup

To attach an on-screen button to a game controller button, simply add the data-pw-gc-button tag to the element. The value of this tag must match the unmappedLocalizedName of the game controller button in iOS.

For example, the following button would purchase the primary product if a user pressed the "A" button on their game controller.

<div data-pw-purchase="primary" data-pw-gc-button="A Button">Purchase</div>


To allow users to style buttons, we will add and remove classes during the button press event. When the game controller input becomes depressed, we add pw-gc-press. When the button is let up, we will remove that class. Many users will use these classes to slightly shirk the button on press and restore it on press end.

.pw-gc-press {
    opacity: 0.9;
    transition: all .2s ease-in-out;
    transform: scale(0.93);


Some users may want to take other actions based on the game controller input so we will automatically forward all game controller events to a function on the window if it is defined.

type DirectionalInput = {
  controller_element: string
  directional: true
  x: number
  y: number
type NonDirectionalInput  = {
  controller_element: string
  directional: false
  value: number

export type Input =
  | DirectionalInput
  | NonDirectionalInput

window.onGameControllerInput = (data: Input) => {
    // Do anything you want with the input!