Paywall

Seven lines of code to make paywalled, premium content on your own website.

Try It

Your tier: checking...
0 Free tier content
1 Premium tier content
2 Premium tier content
3 Premium tier content
4 Premium tier content
5 Premium tier content
6 Premium tier content
7 Premium tier content
8 Premium tier content
9 Premium tier content

Quick Start

HTML
<!-- Add the widget loader -->
<script type="module" src="https://www.inamoon.com/kudos/widgets" async></script>

<!-- Wrap content in inamoon-wall -->
<inamoon-wall subject="email:[email protected]">

  <div tier="0">
    <p>Free content — visible to everyone.</p>
  </div>

  <div tier="1">
    <p>Tier 1 content — subscribers only.</p>
  </div>

  <div tier="3">
    <p>Tier 3 content — premium supporters.</p>
  </div>

</inamoon-wall>

Components

<inamoon-wall>

Wraps content that should be gated by subscription tier. Children with a tier attribute are shown or hidden based on the visitor's global tier level.

AttributeTypeDefaultDescription
subjectstringoptionalCreator identifier for the upgrade link (e.g. "email:[email protected]")
required-tierstringautoOverride the tier shown on the upgrade button (auto-detected from children by default)
no-subscribe-buttonbooleanfalseHide the built-in subscribe/upgrade button

Child elements

Any HTML element inside <inamoon-wall> can have a tier attribute. The value is a number from 0 to 9. Content is shown only if the visitor's tier is greater than or equal to the required tier.

AttributeTypeDescription
tier"0" – "9"Minimum tier required to see this element. Tier 0 content is always visible.

Example:

<div tier="0">Free for everyone</div>
<div tier="1">Supporters only</div>
<div tier="5">Top-tier supporters</div>

Full Example

HTML
<!DOCTYPE html>
<html>
<head>
  <title>My Gated Content</title>
</head>
<body>
  <h1>Welcome to my site</h1>

  <inamoon-wall subject="email:[email protected]">
    <article tier="0">
      <h2>Free Preview</h2>
      <p>This introduction is available to everyone.</p>
    </article>

    <article tier="1">
      <h2>Full Article</h2>
      <p>The complete article, available to Tier 1+ supporters.</p>
    </article>

    <article tier="3">
      <h2>Bonus Material</h2>
      <p>Extra content for Tier 3+ supporters.</p>
    </article>
  </inamoon-wall>

  <script type="module" src="https://www.inamoon.com/kudos/widgets" async></script>
</body>
</html>

How It Works

  1. Load the widget script — the loader registers the <inamoon-wall> custom element
  2. Scan tier children — the component finds all children with a tier attribute and immediately hides tier > 0 content via CSS
  3. Check user tier — the component fetches the visitor's global subscription tier from the In a Moon runtime
  4. Show or hide content — children are revealed if the user's tier meets or exceeds the required tier; an upgrade button appears if gated content is still locked

Content with tier > 0 is hidden before JavaScript runs via an injected CSS rule, so there's no flash of gated content (FOUC). If the runtime is unavailable, a 10-second timeout ensures free content is still shown.

Events

JavaScript
// Fired when tier check completes and content visibility is applied
document.querySelector('inamoon-wall')
  .addEventListener('inamoon:wall:ready', (e) => {
    console.log('User tier:', e.detail.userTier);
    console.log('Has walled content:', e.detail.hasWalledContent);
  });

// Fired when the user clicks the subscribe/upgrade button
document.querySelector('inamoon-wall')
  .addEventListener('inamoon:wall:subscribe', (e) => {
    console.log('Subscribe clicked for:', e.detail.subject);
    console.log('Required tier:', e.detail.requiredTier);
  });

// Fired if the tier check fails
document.querySelector('inamoon-wall')
  .addEventListener('inamoon:wall:error', (e) => {
    console.error('Wall error:', e.detail.error);
  });