Skip to content
Login Contact

Closed article instrumentation for paywall tracking

Marfeel classifies every article into one of three visibility levels that determine content accessibility and user access methods:

  • Open: Free for all users.
  • Dynamically closed: Dynamically closed article icon|42x36 Limited access for specific users.
  • Hard closed: Hard closed article icon|26x26 Exclusive to subscribers.

This visibility setting assists subscription managers and editors in refining the paywall strategy.

Marfeel determines article visibility using the following priority logic:

  • If Marfeel receives a hard closed event, the article is considered hard closed.
  • If Marfeel does not receive a hard closed event but receives a dynamically closed instrumentation event, the article is considered dynamically closed.
  • If Marfeel does not receive any closed event but the article is marked as isAccessibleForFree = false, the article is treated as hard closed.

Article visibility can be specified via standard structured data or via pageVars as described below.

Marfeel automatically detects closed articles based on the isAccessibleForFree structured data field. This field is recommended by Google for SEO, and sites should use it to improve their search positioning. Marfeel reads the same field.

<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "NewsArticle",
"isAccessibleForFree": false
}
</script>

To track the number of closed pageviews, instrument these articles with the closed page var:

window.marfeel.cmd.push(['compass', function(compass) {
compass.setPageVar('closed', 'hard-paywall');
}]);

Articles dynamically closed per user depending on different criteria (like user consumption, pageviews, RFV, or any other metered strategy) must be reported using the closed page var:

window.marfeel.cmd.push(['compass', function(compass) {
compass.setPageVar('closed', 'dynamic-paywall');
}]);

If an article can be dynamically closed for different reasons, the closed page var supports different values. For example, you can report that a pageview was dynamically closed because of a metered signwall strategy:

window.marfeel.cmd.push(['compass', function(compass) {
compass.setPageVar('closed', 'dynamic-signwall');
}]);
IMPORTANT:

Conventionally, pages that are dynamically closed should feature closed page variable values that begin with ‘dynamic-.’ For instance, ‘dynamic-mixed’ indicates that the article experienced both dynamic-paywall and dynamic-signwall.

When an article acquires both hard and dynamic closed data, Marfeel will categorize its visibility as mixed. In this context, ‘mixed’ means an article encountered a hard-paywall along with either of the other two dynamic values.

AMP pages cannot execute JavaScript directly (e.g., compass.setPageVar(...)), so you must pass the closed value via amp-analytics using AMP variables and macros.

  1. Ensure required AMP components are included: Add these to the <head> of your AMP document
<!-- Add the amp-analytics component in the <head> if not present -->
<script async custom-element="amp-analytics" src="https://cdn.ampproject.org/v0/amp-analytics-0.1.js"></script>
<!-- If you use AUTHDATA(...), ensure your AMP access/subscriptions component is configured -->
<script async custom-element="amp-subscriptions" src="https://cdn.ampproject.org/v0/amp-subscriptions-0.1.js"></script>
<!-- or amp-access if that's what you use -->
<script async custom-element="amp-access" src="https://cdn.ampproject.org/v0/amp-access-0.1.js"></script>
  1. Configure amp-analytics with a new closed var
<amp-analytics
config="https://sdk.newsroom.bi/amp.v1.json"
data-credentials="include">
<script type="application/json">
{
"vars": {
"accountId": "/* AccountId */",
"closed": "CLOSED LOGIC"
}
}
</script>
</amp-analytics>

Accepted values for closed (same semantics as web):

  • hard-paywall
  • dynamic-paywall
  • dynamic-signwall
  • Any other dynamic reason as dynamic-*
  • Empty string for open articles.

1) Use AUTHDATA from AMP Access / Subscriptions

"closed": "$IF($EQUALS(AUTHDATA(paywallReason),metered),$IF($EQUALS(AUTHDATA(data.isLoggedIn),false),dynamic-singwall,dynamic-paywall),'')"

2) Force hard paywall on all AMP pageviews

"closed": "hard-paywall"

3) Set based on cookie state (fallback to none)

"closed": "$IF($EQUALS(COOKIE(wall_state),dynamic-paywall),dynamic-paywall,'')"

4) Dynamic signwall when user not logged in

"closed": "$IF($EQUALS(AUTHDATA(data.isLoggedIn),false),dynamic-signwall,dynamic-paywall)"

5) Open article (default). Omit closed If the article is open on AMP, either omit the closed var or set it to an empty string:

"closed": ""

Note: The examples above are illustrative only. You can compute closed with any AMP macros/substitutions you already use to display the paywall; e.g., QUERY_PARAM(...), AMP_GEO(ISOCountry), CONSENT_STATE / CONSENT_STRING, VARIANT(name) / VARIANTS, CLIENT_ID(scope), DOCUMENT_REFERRER, VIEWER, PAGE_VIEW_ID, or RANDOM.

Some macros resolve asynchronously. If they don’t resolve in time, they may delay or prevent the initial pageview hit.

  • Keep all closed values as quoted strings inside the JSON.
  • data-credentials="include" is mandatory to resolve AUTHDATA(...) and read credentials or cookies.
  • You can use any valid AMP macro (e.g., QUERY_PARAM, CLIENT_ID, VIEWER, PAGE_VIEW_ID, etc.).
  1. cs not showing in network requests?
    • Check for validation issues or AMP console warnings.
    • Ensure macros like AUTHDATA(...) are resolving properly.
  2. Empty AUTHDATA response?
    • Confirm your amp-subscriptions or amp-access endpoint returns all required fields.
  3. Cookies not read?
    • Check cookie domain/path compatibility with AMP cache.

If you have isAccessibleForFree=false because of a dynamic paywall, inform Marfeel by instrumenting dynamic closes. If you already have the implementation in place but still see a hard-close icon, there are two possible causes:

  1. You are sending both hard closed and dynamic closed events.
  2. You have isAccessibleForFree = false on an article that has never been dynamically closed. In that case, consider removing the isAccessibleForFree flag, as it sends a misleading signal to Google.

Compass not showing the defined visibility

Section titled “Compass not showing the defined visibility”

Depending on how you load Marfeel’s SDK, you may get an error when calling the setPageVar tracking code:

(index):354 Uncaught TypeError: Cannot read properties of undefined (reading 'cmd')

Protect against this by initializing the marfeel object before calling it:

window.marfeel = window.marfeel || { cmd: [] };
window.marfeel.cmd.push(['compass', function(compass) {
compass.setPageVar('closed', 'hard-paywall');
}]);

On Experience Manager, the closed pageVar can be leveraged as a custom var. This is useful to exclude Experiences from closed articles. It cannot be used in AMP experiences.

How does Marfeel determine article visibility?

Marfeel uses a priority-based system. If it receives a hard closed event, the article is hard closed. If it receives only a dynamic closed instrumentation event, the article is dynamically closed. If no closed event is received but isAccessibleForFree is set to false, the article is treated as hard closed.

How do I track closed articles on AMP pages?

Since AMP pages cannot execute JavaScript directly, pass the closed value via amp-analytics using AMP variables and macros. Configure the closed var inside the amp-analytics JSON with the same values used on web: hard-paywall, dynamic-paywall, or dynamic-signwall.

Why do open articles appear as hard-closed in Compass?

This typically happens when isAccessibleForFree is set to false for a dynamically paywalled article without sending a dynamic closed event. Either instrument the dynamic close or remove the isAccessibleForFree flag if it sends a misleading signal to Google.