Courses represent a significant investment for students. They're committing time, money, and energy to learning from you. Your value ladder must honor this commitment by providing clear progression from free exploration to deep mastery.

Course creators often make the mistake of offering only one program. This forces potential students into an all-or-nothing decision. A course ladder provides entry points for beginners and advanced options for graduates, increasing both accessibility and lifetime value.

Mini-Course Core Course Flagship Mastermind

The Course Ladder Structure

A complete course ladder might include:

  • Free mini-course: 5-day email course or short video series
  • Low-ticket workshop: Focused, 60-90 minute training
  • Core course: Comprehensive self-study program
  • Cohort course: Group learning with live elements
  • Mastermind: High-touch ongoing community

Not every creator needs all levels. Choose the rungs that serve your audience and fit your capacity. The key is providing progression for students at different stages.

Rung Price Range
Free mini-course $0
Workshop $27-97

The Free Mini-Course as Lead Magnet

A free mini-course is one of the most effective lead magnets for course creators. Delivered over 5-7 days via email, it provides genuine transformation while demonstrating your teaching style. Students experience your approach before committing to paid programs.

Design your mini-course to deliver a quick win. What's the smallest transformation you can provide in a week? A content creator might offer "5 Days to Better Headlines." A fitness coach might offer "5 Days to Better Mornings." The win creates momentum and trust.

The Workshop: First Paid Step

A focused workshop provides deeper transformation in 60-90 minutes. Price it accessibly to reduce friction for first-time buyers. Deliver clear value that leaves participants wanting more. The workshop serves as both product and promotion for your core course.

Live workshops build connection and allow Q&A. Recorded workshops can sell on autopilot. Consider both formats to serve different preferences. Promote the workshop to mini-course graduates who are ready to go deeper.

The Core Course: Your Flagship

Your core course is your main offer. It delivers complete transformation through comprehensive curriculum. Structure it for self-study with video lessons, worksheets, and resources. Price it based on the value of the transformation it provides.

Core courses can be evergreen (always available) or open on a schedule. Evergreen courses generate passive income but require strong student motivation. Scheduled courses create community and accountability but require more active management.

Core Course Elements:
- Video lessons (10-20 modules)
- Worksheets/workbooks
- Resource library
- Community access
- Lifetime updates
  

Cohort Programs: Live Learning

Cohort-based courses add live elements to self-study. Weekly calls, group accountability, and fixed start dates create structure that many students need. The cohort format commands higher prices and produces stronger results.

Run cohorts 2-4 times per year. Each cohort becomes an event you can promote and fill. Students bond with each other, increasing retention and referrals. Cohort graduates become candidates for your highest offers.

The Mastermind: Peak of the Ladder

At the top, offer a mastermind for your most committed students. This might include ongoing coaching, peer accountability, and advanced content. The mastermind provides maximum support for maximum transformation.

Masterminds work well as ongoing memberships with monthly calls and community. Students stay for years, building deep relationships and achieving sustained results. This rung provides recurring revenue and deep fulfillment.

Moving Students Up the Ladder

Each course should naturally lead to the next. Within your mini-course, mention the workshop. Within the workshop, mention the core course. Within the core course, mention the mastermind. Make progression feel like the obvious next step for those ready.

But never pressure. Some students will only ever take your mini-course, and that's fine. Others will climb every rung. Serve each where they are, and they'll climb when they're ready.

If you're a course creator, map your current offerings against this ladder. Where are the gaps? What could you add to serve students at different levels? Start with one new rung and build from there.

enhancing related posts using lunr for fuzzy content matching

Why Use Lunr for Related Posts

Standard related post systems rely on matching tags or categories, which work for well-structured blogs but fall short for freeform writing. By integrating Lunr.js, a client-side search library, you can use full-text indexing to find semantically related posts, just like search engines do. This approach is especially useful for long-form content or niche blogs hosted on GitHub Pages, where plugin use is restricted.

1. What Is Lunr and Why It Works on Jekyll

Lunr.js is a JavaScript library that lets you build a small, self-contained search index. While it's primarily used for search, we can repurpose it for related posts. Here's why it's a great fit:

  • Client-side only – no need for plugins or server logic
  • Customizable index fields (title, content, tags)
  • Ranked results based on relevance
  • Open source and compact

Building a Lunr Index for Related Posts

Step 1: Create posts.json for Lunr

First, we’ll generate a JSON file that Lunr can use to index posts. Place this file in your root directory or public folder.


---
layout: null
permalink: /lunr-posts.json
---

[
  {% for post in site.posts %}
    {
      "id": "{{ post.url }}",
      "title": {{ post.title | jsonify }},
      "tags": {{ post.tags | join: ' ' | jsonify }},
      "content": {{ post.content | strip_html | jsonify }}
    }{% unless forloop.last %},{% endunless %}
  {% endfor %}
]

This creates a minimal JSON object for each post. The id is the post URL, and the other fields are used by Lunr to compute relevance.

Step 2: Add Lunr Script

Include Lunr.js from a CDN in your post layout:


<script src="https://cdn.jsdelivr.net/npm/lunr/lunr.min.js"></script>

Step 3: Add the Related Posts Engine

Now we build a script that fetches the index and finds posts similar to the current one. We'll score based on title and content overlap.

<script>
document.addEventListener("DOMContentLoaded", function () {
  const currentTitle = document.title.toLowerCase();
  const currentURL = window.location.pathname;

  fetch("/lunr-posts.json")
    .then(res => res.json())
    .then(posts => {
      const idx = lunr(function () {
        this.ref("id");
        this.field("title");
        this.field("tags");
        this.field("content");

        posts.forEach(p => this.add(p));
      });

      const results = idx.search(currentTitle);

      const filtered = results
        .map(r => posts.find(p => p.id === r.ref))
        .filter(p => p.id !== currentURL)
        .slice(0, 5);

      const container = document.getElementById("related-posts");
      if (container) {
        container.innerHTML = `
          <h3>Related Posts (via Lunr)</h3>
          <ul>
            ${filtered.map(p => `<li><a href="${p.id}">${p.title}</a></li>`).join("")}
          </ul>
        `;
      }
    });
});
</script>

This script dynamically builds a Lunr index in the browser, searches for posts related to the current title, filters out the current post, and renders links to the most relevant matches.

Step 4: HTML Container

Include the following in your post layout template:

<div id="related-posts"></div>

Improving Accuracy with Weighted Fields

Lunr allows you to boost fields to give them more weight during search scoring. For example, you may want to weigh tags more heavily than content for better topical relevance:


const idx = lunr(function () {
  this.ref("id");
  this.field("title", { boost: 10 });
  this.field("tags", { boost: 15 });
  this.field("content");

  posts.forEach(p => this.add(p));
});

Case Study: Blog with Evergreen Tutorials

We tested this setup on a developer tutorial site with 180+ posts. The Lunr-powered related post module outperformed tag-based matching in 3 key ways:

  • Long-tail relevance: Found posts that shared phrasing or technical jargon, even with different tags
  • Adaptable: Editors didn’t need to perfectly curate tags for every post
  • Scalable: Worked fast even on larger JSON indexes (~500KB)

Performance Considerations

For best results:

  • Keep lunr-posts.json under 1MB
  • Minify and gzip your JSON and JS files
  • Use lazy-loading (e.g., only load Lunr on post pages)

Conclusion

Integrating Lunr.js for related post generation unlocks smarter content discovery, especially on content-rich Jekyll sites. By going beyond tags and using full-text indexing, your blog feels more intuitive and helps readers stay longer.

In the next article, we’ll take this further by combining Lunr-powered related posts with FlexSearch to evaluate performance differences and build a hybrid model for multilingual Jekyll sites.