liquidGenerating a Sitemap for Your Teachable School with Liquid
Teachable won't make a sitemap for you, but a short Liquid loop on a hidden page can write one for every lesson in your school. Copy, paste, done.
This is a quick follow-up to Does SEO Work for a Teachable School? Part 1, where I got my school into Google Search Console with a hand-written sitemap.
In that article I said the easiest way to get your lesson addresses was to open the curriculum and copy the links. That's fine for a handful of lessons. My course has 59, and copying 59 links by hand is the tedious job where you miss one, paste one twice, or forget to add the lesson you published last week.
I used a Liquid loop instead.
The idea
Teachable custom pages can run Liquid in a custom code block, and Liquid can loop through every course and every lesson in your school. So you can make a custom page that writes out the whole sitemap for you, already formatted.
A Teachable page can only ever be a web page, never an actual .xml file, so this doesn't give you a live sitemap Google can read directly. What it gives you is the finished text, ready to copy and paste into the sitemap file you host on your own site (Step 4 in Part 1). It takes care of the tedious part - generating the sitemap from your Teachable courses, not the hosting.
The code
Create a new page in your school (I called mine /p/sitemap-generator), add a custom code block and paste this in. Change the base line to your school's address, including your custom domain if you have one.
{%- assign base = "https://purplehippo.teachable.com" -%}
{%- assign today = 'now' | date: '%Y-%m-%d' -%}
<textarea readonly style="width:100%;height:70vh;font-family:monospace">
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>{{ base }}/</loc>
<lastmod>{{ today }}</lastmod>
</url>
{%- for c in current_school.publicly_viewable_courses %}
{%- for section in c.ordered_published_lecture_sections %}
{%- for lecture in section.lectures %}
<url>
<loc>{{ base }}/courses/{{ c.id }}/lectures/{{ lecture.id }}</loc>
<lastmod>{{ today }}</lastmod>
</url>
{%- endfor %}
{%- endfor %}
{%- endfor %}
</urlset>
</textarea>Publish the page, open it, click in the box, select all and copy. Your sitemap is in your clipboard buffer. You'll need to paste that into a text editor and then save the file as sitemap.xml (make sure to save the file as text and be cautious if you use a word processor program like MS Word since they save as .doc by default).
What it's doing
There are three loops, one inside the other:
current_school.publicly_viewable_coursesgoes through every course a visitor can see.ordered_published_lecture_sectionsgoes through each course's sections, in curriculum order, and only the published ones. That matters, you don't want unpublished lessons sent to Google.section.lecturesgoes through the lessons in each section.
For each lesson it writes out one <url> entry with the address and today's date.
I put the output in a
Things to watch
Old courses. publicly_viewable_courses includes every course a visitor can see, so if you still have old courses published they'll end up in the sitemap too. Either unpublish them first, or limit the loop to one course by wrapping the middle section in {%- if c.id == 3033045 -%} and {%- endif -%} (with your own course ID, which you'll find in the address bar when you edit the course).
Locked lessons. Every lesson in my course is public, so I can list them all. If your course is paid with only a few free preview lessons, the locked ones shouldn't go in the sitemap, because Google will only get the sign-in page. I haven't tested a reliable way to pick out the preview lessons in Liquid yet, so for a paid course I'd check the list by hand and remove the locked ones.
Sales pages and custom pages. The loop only covers the homepage and lessons. Add your sales page and any custom /p/ pages you want found by hand, at the top of the list. They don't change often so it's not much work.
Hide the page. Keep the generator page out of your navigation, and don't put it in the sitemap itself. It's not harmful if someone finds it, it's just not something you want showing up in search results.
When to run it again
Whenever you add, remove or reorder lessons, open the page, copy the new version and replace the file on your site. Search Console will pick up the change next time it reads the sitemap, or you can resubmit it to hurry things along.
It takes about five minutes to set up and saves copying every lesson link by hand.
Purple Hippo Web Studio
Need this built, not just documented?
We build custom Teachable integrations, webhook infrastructure, and B2B enrollment portals. Fixed scope, fixed price, no surprises.
Get in touch