Paywall integrations normally need 2 implementations on Marfeel's side:

  • Extractor - Get the content behind the paywall.
  • AuthProvider - Grant access to paid content to readers with an authentication token by validating it.


In order to have all the client's articles in the database, Marfeel needs access to the premium content. 

The extractor logs in with the given credentials to the appropriate endpoint. If the login is successful the cookies are returned to Gutenberg Content Connector and stored. This is necessary for the extractions of the premium content to work. 

The extractor is an implementation of


When a user tries to access the Marfeel version of a client's website, they need to be able to log in and see the client's premium content. class takes care of this by receiving an authentication token from the Marfeel Progressive WebApp (PWA). Marfeel then validates the authentication token with an endpoint that the publisher has built specifically for this. Usually it's something like:


Marfeel does not store any of the user's data; it only passes the token to the tenant's server and if they're correct gets a response along the lines of valid : "true".

Marfeel then communicates this to the front-end that the user has access to premium content.


When a user accesses an article through a deeplink, Marfeel doesn't know if this article is premium because the click is not coming from the section mosaic, and therefore can't show the iframe for the user to log in.

The solution to this is the PremiumBlocksFinder class which checks for a specific string in an article when deeplinked. If, for example, a string resembling the following exists in the article, this indicates it's a premium article:

"Do you want to read more? Login here"

In these cases, Marfeel shows the top part of the article and a "Sign in - Sign up badge" so that the process can kick-off.


Marfeel has to inform Gutenberg about the paywall extractor and authprovider to be used:





In the whitecollar, Marfeel must define the premium articles, using the following which allows the detection of premium articles on the home page or sections:

if(isPremium(articleNode)) {
    item.isPremium = true;

function isPremium(articleNode) {
    return articleNode.querySelector('.lock') != null;


Marfeel agents have to implement this file in the layouts folder. The content of this file will appear when a user deep links into a premium article. A snippet like the following should be provided:

<h4>Want to read more?</h4>
<div class="mrf-premiumBadgeLink"><span><div class="btn">Login here</div></span></div>

On the mrf-premiumBadgeLink a click event is added that leads to the login iframe.


In main.js Marfeel has to define the paywall properties like the gateway URL (the src of the iframe implemented by the client) where the user will log in.

In this iframe, Marfeel provides ?callback_url= as a parameter which is the callback that the iframe will redirect to, if the user has successfully logged in.

The callback usually redirects to the following which is a file implemented by Marfeel:



The following is an example of main.js properties for which had a paywall integrated:

marfeel.tenant.Paywall = {

        authGatewayUrl: function() {
            var currentEnvironment = window.marfeel.GardaMarfeel.getEnvironment(),
                gatewayUrl = "",
                callbackUrl = "";

            if (currentEnvironment === "localhost") {
                callbackUrl = "http://localhost/statics/";
            } else {
                callbackUrl = window.marfeel.resourcesHost + "/statics/";

            gatewayUrl += "callback_url=" + callbackUrl;

            return gatewayUrl;

    policy: new PremiumArticlesPolicy()


Marfeel must also include the ArticleDetailPremiumBadge in the main.js, otherwise the mrf-premiumBadgeLink will not work.


This file must be included in the index/folder of the client. When completed, Marfeel can link to <tenantURI>/statics/


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 (function () {
 function getUrlParam(param) {
 var queryParams =,
 queryParams = queryParams.split("&");
 for(var i = 0; i < queryParams.length; i++) {
 queryParam = queryParams[i];
 queryParam = queryParam.split("=");
 if(queryParam[0].indexOf(param) > -1) {
 return queryParam[1] ;
 return "0";
 var authData = getUrlParam("token");
 parent.postMessage('{"scope":"authgateway","action":"close","authData":"' + authData + '"}', "*");