SEO and Paywalling Best Practices
When you gate article content, search engines need to understand that the content is intentionally paywalled. Ezoic Subscriptions gives you the access and checkout layer, but your page markup should still follow Google's paywalled-content guidance.
Use Google's official documentation as the source of truth: Paywalled content structured data.
Recommended Page Structure 🔗
Keep teaser content visible to everyone, then wrap subscriber-only content in a real CSS class such as .paywalled-content.
<article>
<div class="article-teaser">
<!-- Headline and first paragraphs visible to everyone -->
</div>
<div class="paywalled-content" data-premium-content hidden>
<!-- Soft gate: full body lives here, revealed after access. -->
<!-- Hard gate: fetch and inject the body after access instead. -->
</div>
</article>
In this example:
.paywalled-contentis the CSS selector used by structured data.data-premium-contentis the element your Ezoic Subscriptions script reveals after access is allowed.hiddenstarts the subscriber-only section hidden for a soft gate.
If you use a hybrid or server-side approach, keep the same selector on the gated container and fetch or render the protected body only after access is allowed.
Add Paywalled-Content Structured Data 🔗
Add isAccessibleForFree: false and hasPart to your Article or NewsArticle structured data. Replace the example values with the real values for your article.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "NewsArticle",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://example.com/article-url"
},
"headline": "Article headline",
"image": ["https://example.com/article-image.jpg"],
"datePublished": "2026-06-18T08:00:00-07:00",
"dateModified": "2026-06-18T09:00:00-07:00",
"author": {
"@type": "Person",
"name": "Author Name"
},
"description": "Article teaser or summary",
"isAccessibleForFree": false,
"hasPart": {
"@type": "WebPageElement",
"isAccessibleForFree": false,
"cssSelector": ".paywalled-content"
}
}
</script>
If your page already has Article or NewsArticle JSON-LD, merge the paywall fields into the existing object instead of adding a conflicting duplicate article record.
cssSelector Requirements
🔗
The cssSelector value must point to the gated content container on the page.
Use:
"cssSelector": ".paywalled-content"
when your HTML contains:
<div class="paywalled-content" data-premium-content hidden>
<!-- Subscriber-only content -->
</div>
Do not point cssSelector at a missing class. Avoid nested paywalled sections unless your structured data accurately describes each gated section.
noindex or robots-block gated pages that should rank in Google. Do not serve different article HTML to Googlebot based only on the user agent. Do not cloak full content to crawlers while showing unrelated or lower-quality content to users. For hard server-side walls, allow crawler access only after verifying crawler identity; do not trust a Googlebot user-agent string by itself.
Social Previews 🔗
Social previews should not depend on subscriber state. Use teaser-level metadata that is safe for every visitor:
og:titleog:descriptionog:imagetwitter:card
Do not require authentication before social crawlers can read these tags.
Caching 🔗
Be careful with caches on gated pages:
- Do not accidentally cache subscriber-only HTML for anonymous visitors.
- Do not let an anonymous version overwrite the subscriber version for signed-in visitors.
- If your site fetches the protected body after access is allowed, keep that response private to the visitor session.
Validate Before Launch 🔗
Before you launch a gated article:
- Test a live URL with Google's Rich Results Test.
- Confirm the rendered HTML includes the JSON-LD.
- Confirm
cssSelectorpoints to the gated content container. - Use URL Inspection in Google Search Console after the page is live.
Validation does not guarantee ranking or rich-result display, but it helps catch markup mistakes before they affect search visibility.