5

I've got a site with some paywalled articles. We want to ensure that Googlebots can index the paywalled content, but we don't want to be accused of cloaking.

I've got two types of articles:

  1. Premium articles, which use a backend paywall. If the user has a subscription, the paid contents will be rendered serverside. If the user doesn't have a subscription, the server will just render an article with a paywall and no paid contents.

  2. Standard articles, which use a frontend paywall. The full article is always rendered serverside. Then some clientside code is responsible for determening if the user is a subscriber, or if you get this article as a freebie (everyone gets 3 free Standard articles per week). If you're not allowed to read the article, the DOM-nodes containing paid contents will be removed by javascript, and replaced with a paywall element.

I want to ensure that Googlebots can index the paid contents in all my articles. We will basically treat the Googlebot as a subscribed user. (by checking user-agent and validating IP adress using reverse DNS-lookups)

But I don't wanna be accused of cloaking.

The question is: What should my json-LD look like?

I would imagine this is what I should be using (for both types of articles)

"hasPart":[  
      {  
         "@type":"WebPageElement",
         "isAccessibleForFree":false,
         "cssSelector":".paid-content"
      }
   ],
   "isAccessibleForFree":false

Would this work in my case?

All the examples I've found on Google related to cloaking deal with situations where you hide the paid contents with CSS.

My situation is a bit different, since I remove the .paid-content element completely. (Either serverside or clientside)

1

1 Answer 1

2

The JSON-LD syntax in your example is wrong. Here's an example of an article schema with paywalled content:

<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>

How you handle that on your own application is up to you I suppose, but the content should still remain crawlable in your source code so that Google can properly crawl/index your page.

Additional guidelines: https://developers.google.com/search/docs/advanced/structured-data/paywalled-content

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.