Transcript
Patrick Ford leads our customer success team, and we are really excited to be discussing how we built the Softr Academy with you all, and generally how you can build an LMS with Softr. This is more of a breakdown session showing you how we built it and discussing the technicalities of how to structure your database, how to structure that data in Softr, and how to use some custom code to expand functionality.
We are going to get started with what a learning management system is, how we thought about structuring it for Softr's purposes, and then we will show you our academy and some of the important parts. Next, we will get into the database structure to show you how we organized that data. Then we will move over to Softr to show how we built some of our core pages and how we are using that structured data, including action buttons for certain CRUD functionality that auto-updates records and navigates between them so we can track key metrics along the way.
A learning management system is a software application designed to manage, deliver, and track educational courses or training programs. It provides tools for creating and organizing content, monitoring students' progress, facilitating communication between learners and instructors, and administrating assessments. We will also show you how we built the Softr certifications within our LMS during this session.
At Softr Academy, we have 12 different courses or learning tracks hosted in this LMS, containing over 100 different lessons. We have a lot of content that we need to provide to our users in a very effective and straightforward way so you can get what you need right when you need it. It is also really important to have built-in statistics tracking mechanisms so you can see how your learners are doing.
Some of the fields we track at Softr include course completion, meaning whether a user went through the entire course and completed it. Another thing we track is lesson completion, so whenever a student completes a lesson, we save that to the user record to see which lessons they have taken. We also track the total number of students, active learners, certification attempts, whether they received the certification, when they were last active, academy feedback, and their learning level.
We collect all of this data as part of the experience so you can see if the content is beneficial, if people are enrolling, and if they are completing the courses. This setup is built completely with Softr using Airtable on the backend, moving soon to Softr Databases.
Once you navigate to the academy, you will see our dashboard page, which serves as the home to our learning center and directs users in several ways. We recently built an updated Getting Started with Softr series where you can learn Softr in 60 minutes or less.
There are seven or eight total lessons there, each breaking down a core concept that we believe is really important for you to learn in order to learn Softr. We direct users right there because we think that is going to be a great ramp for them, using our UI and UX to draw attention in that manner. Next up, we have our quick link blocks.
These are the static blocks in Softr that make it really easy to navigate users to specific areas or URLs. In our case, we send them to the product docs, our community forum, or to get help with our support. All of these are essential options when you are trying to learn Softr for the first time, and we want to make sure you are connected to that.
Finally, we have our courses down here, along with our core concepts and all videos where you can search. There are over 150 videos here, and the really cool part is that we have tags associated with all of them. These are all the videos that we support, and if you need something about authentication, action blocks, or Stripe integration, searching is a quick way to get there.
Because of the Softr built-in search feature, we are able to search a lot of different fields very quickly and natively to get users the information they want when they need it. We are using our tab block for this, along with some inline filtering and search functionality to complete this experience. Next, I want to bring you to our course detail page, and then I will back up a little bit to show you the database behind it.
We are now on the course detail page, and we have an item details block at the top showing you that this is the course detail page. On this detail page, we have breadcrumbs up here, which use a little bit of custom code with our embed block to create that functionality. We also have our preview image here.
This preview image is reading the detail record to pull in the image that relates to the course we are viewing. If I were to go to a detail page for our client portal course, you would see the client portal image here. This is one dynamic page that we created for all of our courses to showcase their important details.
That is really the beauty of the item details block: it is a dynamic block that reads data and displays it dynamically. Even though we have 12 courses, we just build one page, and that single page services all 12 of those courses. Beyond that, we have some more detail blocks with an action button, and then we have related lessons.
Related lessons are what we call linked lists in Softr. We have a database structure called lessons, and we look for lessons that relate to the current page course. We tell the list block to find all the lessons that belong to the getting started with Softr course and display them here using a conditional filter.
In order to do that, we need to save that course and the related course on that lesson data type. Let us go over into our database to show you this structure, and then we will come back into the Softr editor to show you how we made all this come together.
Here we are in our Airtable base, looking at our users table. This is just a test view with test data so you cannot see any real user data. This is the user table that folks use when they log into Softr Academy.
If we were to go into Softr, we would see users and all the user records connected through this linked table. This academy base services a lot of things for us, so there might be extra fields that you would not necessarily need in a standard LMS. On this table, we have the user name and email, as well as a field for courses taken.
Courses taken is a relationship field linking to our learning tracks, which is what we call our courses. Anytime a user enrolls in a course, we save it to the user record so we can see what courses they are enrolled in. Since we have 12 different courses, it is important to know which specific ones they joined.
Beyond that, we also have a field for courses completed. We have a backend automation checking whether they enrolled in and completed all the lessons that were part of that course. If so, it marks that course as complete on that user record.
We are running those automations right now using Airtable automations. They detect if all the lessons belong to that user and then update the field accordingly. That allows us to track the course enrollment to course completion rate, which is another useful metric to monitor.
How is it determined whether or not they completed a lesson and thus a course? We are in the Softr studio right now. Within that, you can see a lot of different blocks, and it looks different than what you might have seen in the preview that I was just showing you.
The reason is that these three different blocks are set up for three different responsive settings. I want to make sure that this academy looks good on every single device that you are viewing. These specific images were hard to do in a one-off way where one image would work for everything.
In this case, I have three blocks and I am controlling the visibility based on device visibility for each of them. I have updated the name so this is the detail block for tablet, and it is only going to show up on tablet. This way, on each of the pages, I am making sure that the images and related details are styled in that specific way.
To answer your question, we are using action buttons for this. We are using the one-click update action button to say that when you click this, we are going to add this course to the logged-in user. It updates the enrolled students field by adding the logged-in user's email.
By clicking this button, the user enrolls in the course, and that course record is added to the user's relationship field to show that they have enrolled. The same logic is applied for the lesson. When you click on the related lessons, we have action buttons that do the same thing with a one-click update.
You might be asking how to actually go to that lesson after updating. We accomplished this with custom code, inserting a window event listener that looks for an update record success event. When the one-click update is finished, it redirects us to the first lesson URL.
[.blog-callout]
Note from Softr: Softr Workflows keeps the logic next to the app instead of relying on custom code listeners or external tools.
[.blog-callout]
Let me show you how I pre-built these URLs in our database to work with this setup. Going over to our database, in our lessons table, I have structured the lessons by each of our courses and learning tracks. There is a good amount of lessons across the tracks.
Within the learning track for actions, where we teach you how to use action buttons for adding and updating data, we have lesson numbers, durations, cover images, descriptions, and the YouTube URL used to display videos inside Softr. At the end, we have a dynamic field for the next lesson URL. This pre-builds URLs in the database based on what lesson comes next.
It directs the user to the academy lesson detail page and loads the record ID for the upcoming lesson. That way, when clicking next lesson in Softr, the action button simply opens that dynamic URL. It loads the detail record, finds the prepared lesson URL, and navigates to the next lesson detail page.
This makes it super dynamic because whenever you add a course or lesson, you only add the necessary information in Airtable, and the formulas handle the back end. You do not have to change anything about the Softr pages or blocks on the front end. The next lesson URL is generated using a root URL and a formula that appends the next lesson record ID.
When a new lesson is added, the formula updates automatically without requiring edits in Softr. Instead of having thirty different action buttons, you have one action button dynamically pulling from the database data. Softr is moving toward being a full-stack platform.
Can you explain a little bit about the workflows that are coming and how it will make it much easier to build these types of flows even outside of custom code? If we go back over to Softr, we have noticed that there is a little bit of custom code required for this multi-step flow: update the record and then navigate to the next page. Right now we have the ability to update the record, but then it leaves the user on that page and they have to click another button to go to the next one.
I did not think that was the best user experience. Because Softr is extendable, I was able to add a window listener event to have that one button handle multiple actions. With workflows, this is going to be done natively and visually without code.
You will be able to set up logic similar to Zapier or Make, updating a record in step one and navigating to a page in step two. This can expand to many other functionalities, such as making an API call, saving the generated value to a record, and navigating within Softr.
[.blog-callout]
Note from Softr: Softr Workflows keeps logic and multi-step automations right next to the app instead of relying on third-party tools or custom code.
[.blog-callout]
Workflows is coming around June, and we are also getting ready for tables, which is our native database version. It is an Airtable-like database connected directly inside Softr for better performance and response times.
Let us continue with the database, and then we will look back into Softr. There are some other mechanisms we need to examine, including documentation. Connecting a new learner with related documentation was really important to us so they can get answers right away.
On the lesson page, you see an action button appear that only displays when relevant documentation exists. In the Softr action settings under button visibility, we set a conditional rule to only show the button when the documentation field is not empty.
When a user clicks that button, it opens a sidebar modal that loads the documentation related to that lesson. This keeps the learning experience clean and contextual.
To build that relationship, we have a table called documentation in Airtable. In that table, you create a new record and assign it to a related lesson as a linked record. Dynamically, that makes the documentation available inside Softr.
It is slightly manual because you need to assign the appropriate doc to each lesson, but it makes connecting core docs to the video lessons seamless. In Softr, clicking the button loads a modal with an iframe showing that documentation link, which is pulled dynamically from the lesson detail page data.
Structuring your data in a creative way unlocks many possibilities with Softr. You can display data dynamically so that you only add it once, and it automatically shows up across pages serving multiple purposes. Linked records work exceptionally well for any application, whether you are building an LMS, managing projects with tasks, or mapping relationships between people.
It helps to think about the nouns of your app, such as courses, lessons, users, documents, resources, comments, or feedback. These are all stored records, and you connect those tables together using linked record fields. From there, you can build out everything you need on the Softr front end.
To answer the question about how hard it is to create lessons for internal users without code: it is not hard at all. Only about two percent of our setup used code, and that was purely for advanced tracking purposes like enrolling a user in a lesson before navigating to the next page. You could simply navigate to the next page without code and be completely fine.
When setting up the app in Softr, three pages are especially important. Beyond the dashboard, we start with the course listing page, which displays all of our learning tracks. This page uses a hero block followed by a list block.
The list block pulls dynamic data from our learning tracks and filters them by learning type. If the type is set to course, it appears here, whereas items categorized as core concepts are directed to a separate page. Clicking on any course in the list takes the user directly to the course detail page.
The course detail page dynamically displays the specific information for that course, including the ability to play the initial video. It also contains a linked list showing all the lessons related to that specific learning track. Because of that relationship, all relevant lessons populate automatically on the detail view.
Clicking on a course opens the course detail, and clicking on an item within that page opens the lesson detail. Those are the three core pages needed to build an LMS: the course listing, the course detail, and the lesson detail. Users can navigate through their courses, select a lesson, and immediately start playing the content.
There are two ways to add new lessons. You can build an admin page in Softr with a form that allows users to submit new course data directly into Airtable. Alternatively, you can enter the data directly into Airtable yourself, defining the courses and lessons manually before Softr displays them.
For simpler use cases, such as HR onboarding, you might only need to provide training materials and track which employees have viewed them. Setting up this workflow requires a slightly different approach depending on user authentication.
To track whether a user has enrolled in a course or viewed specific lessons, that user must be logged in. To handle this, we created separate views tailored for non-logged-in visitors versus logged-in users. Separating these experiences allows you to gate interactive features, such as leaving comments, exclusively to authenticated members.
We have a static block that explains you cannot comment unless you log in, and then we direct them there. This creates a distinct user experience and flow for logged-in versus non-logged-in visitors. By separating these paths at the tab level, I can build all of these tabs with that distinction in mind.
Similarly, you need to log in to leave feedback so that we can properly collect and attribute it. Resources work in a very similar way to our documentation. We have related documentation that pulls up to explain how to use a feature.
Sometimes we also want to include the Airtable base for a lesson so viewers can see the actual data structure being taught. In this case, we have another table in Airtable called resources, structured the same way as our documentation. Within resources, we link the base to the lesson it relates to.
[.blog-callout]
Note from Softr: While Softr integrates with more than 17 external sources like Airtable, Softr Databases is the native way to hold your data inside Softr with better performance.
[.blog-callout]
This tab conditionally displays depending on whether the resources field is empty or populated. If resources exist, the tab appears so users can access the base and inspect the underlying database structure. It provides a personalized experience for documentation, resources, questions, and feedback within your LMS using Softr without code.
Having logged-in users is critical for tracking progress. For our project, it was important that anyone could access the content whether logged in or not, which is why we built two separate experiences. If users are not logged in, we cannot track their learning journey as effectively.
From an administrative standpoint, an organization might require everyone to log in to enforce complete tracking. In our case, we wanted people to access the content and learn Softr immediately without barriers. Everything is public-facing, so users do not need authentication to navigate and complete lessons.
We then enrich the experience to encourage account creation so we can track progress and collect feedback. Restricting features like comments is one way to encourage users to sign in. This allows us to see who is succeeding and interact with them directly.
Regarding the question about having a user mark their location coordinates on a map to trigger a form with dropdown tags and text, that is very specific. You would likely need custom code to pull location coordinates from an IP address using external JavaScript libraries. While you can embed custom code in Softr, this is not a native feature since our focus is primarily on internal business use cases.
Address fields are available in conditional forms, which might handle parts of that workflow if connected with a Google Maps API key. However, fully interactive map coordinate picking usually requires additional custom logic. Tracking progress operates along similar lines using action buttons.
When looking at the watch lesson button for a logged-in user, we display remaining lessons and watch again options. For non-logged-in users, the button simply opens the details page. For logged-in users, we use a one-click update action button to save progress.
Instead of just opening the details page, the one-click update adds the logged-in user to the list of people enrolled in that lesson. That records the user as a participant, allowing their ongoing progress to be tracked and displayed.
We are using custom code again at the page level where we listen for that window event listener for the specific event of update record success. We use a window location reference to then send them to that lesson detail page for the item clicked on, bringing them to the next page. I can put this code in our forum after the call if anyone is interested in using these event listeners for tracking an update record and navigating the user afterwards.
Part of this navigation requires the next lesson record ID, which is pre-built in our Airtable database. We are pre-building what that next lesson is, so it is either the next lesson or the current lesson. We have both of those URLs pre-built, and then in this custom code, we navigate them accordingly.
To be clear, this is not tracking specific progress through a video, but whether or not they have visited a lesson. You do stuff on the backend with Airtable automations or any kind of automation to say they have taken a certain number of lessons out of the total, calculating their progress through the course. That is handled with data manipulation and backend automations.
[.blog-callout]
Note from Softr: Softr Workflows keeps logic and automations directly inside your app instead of relying on external tools or database scripts.
[.blog-callout]
For Sarah's question about tracking when you start and complete a lesson, as soon as you click on a lesson, we treat it as completed. It would be great to have start and finish states, but we have not gotten to that level of detail yet. We are simply saying that once you click on it, we add that lesson to the completed list.
David asked about displaying more action buttons instead of the default behavior where third and additional action buttons are hidden behind a three-dot menu. Providing two main actions for the user is a UX best practice so we do not overwhelm them with too many choices across the screen. While there is custom code functionality available, keeping it limited helps maintain responsiveness across mobile and tablet devices and ensures clear visual hierarchy.
Regarding whether a non-logged-in user can see their progress, they cannot because we are not able to save any data to a user record if they are not logged in. Logged-in users have their progress saved to their account, allowing for a personalized tracking experience.
For logged-in users, we display remaining lessons and a watch again section. All the lessons they have watched go into the watch again tab, while the remaining uncompleted lessons stay listed below the current lesson. To configure this list, we go to our data source and add a conditional filter to only show lessons belonging to the current course where the logged-in user is not yet linked as having completed it.
Cosman asks if there is a chance to build a quiz. We have quiz capabilities within Softr, which we use for our Softr certification. We are using an external system to handle this correctly, so let me talk you through how that works.
In our Softr certification app, I can log in as a preview user, which is very helpful. This static block detects if the user has filled out their name or not. Right now, it shows that the user has not added their name, which is required because we need to attach their name to the certification.
Otherwise, you see this Softr certification embed form pulling from a system called ClassMarker, which is where we create our quizzes and events. We assign questions to these quizzes in ClassMarker and export them via an embed. We then take that embed code and place it into our custom code block in Softr.
Along with embedding the quiz, we pass the Softr user's email, record ID, and full name back to ClassMarker. This allows ClassMarker to identify the student taking the quiz and group their attempts automatically. When a quiz is finished, webhooks from ClassMarker ping our database with the related record ID and the results showing whether the student passed.
Based on those database updates, we use user groups to track how many times a user has attempted the quiz and whether they passed. We give the user up to three chances to pass, locking them out for six months after a failed attempt for our metrics. Each step updates dynamically based on these logged attempts.
We have a table for certification attempts, and an automation in the background receives the webhook from ClassMarker to create the record linked to the user. From there, dynamic user groups determine the student's status based on their attempt history. This allows us to display different quizzes or lockout messages on the certification page conditionally.
The reason you see three different quizzes is that they are shown conditionally based on the user group. Once a quiz is taken, the webhook logs the attempt, updates the database, and assigns the user to the next user group, which surfaces the next quiz attempt. If they reach the attempt limit, the user group updates to show the attempts reached block.
Having three separate quizzes helps maintain the integrity of our certification. Because users can take it up to three times, serving different questions prevents people from simply memorizing the answers. This ensures that anyone who passes our Softr certification is a true professional.
While Softr forms have evolved, ClassMarker handles specialized quiz features under the hood, such as scoring logic, grading, and routing. Using a dedicated tool via embed is often much more efficient than manually building complex conditional logic for every single question from scratch.
The way that we deal with ClassMarker, we just upload our quizzes, and then it is all built for us automatically. With conditional forms, you might be able to make quizzes, but the way that we saw this as a scalable approach, ClassMarker made the most sense for us. Softr can do a lot of things and you can really push it far, but sometimes there is a better tool for the job, and we recognize that and use it for that reason.
ClassMarker has been a great tool for us. We are using the embed block and are able to send data from the logged-in user to ClassMarker via that API integration so they can see which student is actually taking the quiz, and we can log it back to the user successfully. That does come up from time to time where people have a very specific niche requirement inside of Softr, and while Softr is extremely versatile, there are instances where you may need to integrate a third-party tool or use custom code to bridge that gap.
[.blog-callout]
Note from Softr: If you need custom components or specialized interactive features, the Vibe-Coding block generates the exact custom component from a prompt and wires it directly to your data.
[.blog-callout]
It has really been great seeing the possibilities of what we are able to build with Softr. We are currently working on our updated comments block. In the lesson detail, we had the comments block quite outdated, but we are about to get an updated comments block with built-in email notifications and features that will expand the functionality and make it more natural to comment on lessons and ask questions.
Generally, it took me about 15 to 20 hours to put this entire academy together. To be able to do that as a developer and build a custom academy for your own purposes with tracking and everything you need in an LMS-like way is pretty respectable. This is something that you could do for your organization, your company, or your community.
You can put it on your own custom domain, brand it how you want, and display it how you want. You can also serve it internally for your employees. What you can do is up to you, but Softr makes this much easier to build and digest for your users.
This use case comes up a lot on sales calls, and it is an amazing way to distribute courses and trainings. We have also gotten requests for LMS templates, which could be a great addition in the future.



