Using Perplexity.ai, I was able to get it to create a metered paywall which gives users 3 free articles to read and then pushes them to subscribe.
I think this is a super important feature that I wish Ghost would make native. Also solves the issue of content being behind paywall and Google not being able to properly index it.
Hope this code helps other people. You just paste it in the injection footer.
If you need to make changes to your specific site, just tell perplexity what you want to do and it will create it.
Prompt is " For ghost.org, make me a paywall that pops up if the user is not logged in and has viewed 3 articles. Don’t include the main page when counting, which is https://totalfootball.ghost.io For each free article the user reads, pop up on the lower left side of the screen reminding them how many articles they have left. Make it appear the entire time. Put all the code including script tags in one block so I can paste it in."
Code is below. Update it with your site where it says MAINPAGE.
<script>
(function() {
const ARTICLE_LIMIT = 3;
const MAIN_PAGE = 'https://totalfootball.ghost.io';
const STORAGE_KEY = 'ghostArticleCount';
function createCounter() {
const counter = document.createElement('div');
counter.style.cssText = `
position: fixed;
bottom: 20px;
left: 20px;
background-color: rgba(0, 0, 0, 0.7);
color: white;
padding: 10px;
border-radius: 5px;
font-family: Arial, sans-serif;
z-index: 9999;
`;
document.body.appendChild(counter);
return counter;
}
function createPaywall() {
const paywall = document.createElement('div');
paywall.style.cssText = `
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.9);
display: flex;
justify-content: center;
align-items: center;
z-index: 10000;
`;
paywall.innerHTML = `
<div style="background-color: white; padding: 20px; border-radius: 5px; text-align: center;">
<h2>You've reached your free article limit</h2>
<p>Please log in to continue reading.</p>
<button onclick="location.href='/signin/'">Log In</button>
</div>
`;
document.body.appendChild(paywall);
}
function incrementArticleCount() {
let count = parseInt(localStorage.getItem(STORAGE_KEY) || '0');
count++;
localStorage.setItem(STORAGE_KEY, count.toString());
return count;
}
function showCounter(count) {
const counter = createCounter();
counter.textContent = `${ARTICLE_LIMIT - count} free articles left`;
}
function init() {
if (window.location.href === MAIN_PAGE) return;
if (document.querySelector('body.post-template')) {
const count = incrementArticleCount();
if (count >= ARTICLE_LIMIT) {
createPaywall();
} else {
showCounter(count);
}
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();
</script>