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.
| Attribute | Type | Default | Description |
|---|---|---|---|
| subject | string | optional | Creator identifier for the upgrade link (e.g. "email:[email protected]") |
| required-tier | string | auto | Override the tier shown on the upgrade button (auto-detected from children by default) |
| no-subscribe-button | boolean | false | Hide 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.
| Attribute | Type | Description |
|---|---|---|
| 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
- Load the widget script — the loader
registers the
<inamoon-wall>custom element - Scan tier children — the component finds
all children with a
tierattribute and immediately hides tier > 0 content via CSS - Check user tier — the component fetches the visitor's global subscription tier from the In a Moon runtime
- 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);
});