Monetization
β Improve this pageJekyllLMS gives you two independent monetization tools: locked lessons that
redirect to a paid platform, and a curated set of AdSense placements. Both
are opt-in via front matter and _data/.
Free vs. Locked Lessons
Every lesson has a free: flag in its front matter:
---
title: "Arrays & Tuples"
course: typescript-mastery
order: 4
free: false
---
free: true(or omitted) β the full lesson renders normally.free: falseβ the lesson page shows the first ~40 words as a teaser, replaces the video frame with a lock screen, and renders a **βContinue on"** call-to-action that links to the course'saffiliate_url`. The curriculum sidebar shows a π instead of a duration badge for that lesson, and the course pageβs lesson-accordion shows the same lock badge.
This lets you publish a few free preview lessons (so the course is genuinely
useful and indexable) while the rest of the curriculum lives on a paid platform.
_lessons/typescript-mastery/04-arrays-tuples.md onward in the demo content is
set up this way β read it as a working example.
Linking to an External Platform
Set these on the course, not the lesson:
---
free: false # the course overall isn't free-hosted
platform: udemy # shown as "Continue on Udemy"
price: "$19"
affiliate_url: "https://www.udemy.com/your-course/?ref=youraffid"
---
platform and affiliate_url drive every locked-lesson CTA and the ββ Also on
β button on the course detail page. A fully free, self-hosted
course just sets free: true and platform: self-hosted and skips
affiliate_url β every lesson can stay free: true.
AdSense Slots
_data/ads.yml has two parts:
placements:β the slots actually wired into templates today, referenced from templates assite.data.ads.placements.<placement>.id:in_article/blog_sidebar/blog_in_feed/blog_in_feed_2β blog listing + postpost_sidebarβ single post sidebarcourse_bottomβ bottom of the course curriculumlesson_sidebar/lesson_bottomβ lesson playercatalog_footerβ bottom of/courses/home_featureβ homepage, below the herodocs_footerβ bottom of/docs/
all_slots:β your full AdSense ad-unit registry, so any slot can be dropped into a new spot later without re-creating it in the AdSense dashboard.
To add a slot to a new page, pick an entry from all_slots (or add your own)
and call the shared include:
{% include ad.html slot="1234567890" label="My Ad" %}
or reference a named placement:
{% include ad.html slot=site.data.ads.placements.blog_sidebar.id label=site.data.ads.placements.blog_sidebar.name %}
Ads only render once adsense_id is set in _config.yml β until then every
slot shows a dashed placeholder box, so the layout looks correct in
development without serving real ads. JekyllLMS intentionally does not
wire every registered slot into a page at once β AdSense limits ads per page
and a cluttered layout hurts both UX and RPM. Add slots deliberately.