However you want handle it, whether via CSS or JS; When you view the source code of the page, as long as all your markup is there, Google will crawl the content.
We have a schema for this - So you'll want to add structured data for to denote subscription/paywalled content. We need to semantically bind the paywall with the content on page. To do this use schema.org's cssSelector property.
<html>
<head>
<title>Article headline</title>
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "NewsArticle",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://example.org/article"
},
"headline": "Article headline",
"image": "https://example.org/thumbnail1.jpg",
"datePublished": "2025-02-05T08:00:00+08:00",
"dateModified": "2025-02-05T09:20:00+08:00",
"author": {
"@type": "Person",
"name": "John Doe"
},
"publisher": {
"name": "The Exemplary Times",
"@type": "Organization",
"logo": {
"@type": "ImageObject",
"url": "https://example.org/logo.jpg"
}
},
"description": "A most wonderful article",
"isAccessibleForFree": "False",
"hasPart":
{
"@type": "WebPageElement",
"isAccessibleForFree": "False",
"cssSelector" : ".paywall"
}
}
</script>
</head>
<body>
<div class="non-paywall">
Non-Paywalled Content
</div>
<div class="paywall">
Paywalled Content
</div>
</body>
</html>
Few guidelines here from Google:
- JSON-LD and microdata formats are accepted methods for specifying structured data for paywalled content.
- Don't nest content sections.
- Only use .class selectors for the cssSelector property.
So then this is your markup which includes the div.paywall
we set in our JSON-LD earlier.
<body>
<p>This content is outside a paywall and is visible to all.</p>
<div class="paywall">This content is inside a paywall, and requires a subscription or registration.</div>
</body>