Add-Ons
Unlock more possibilities for your LMS.
Integrations
Connect with tools you already use.
Migration
Switch to Tutor LMS with confidence.
Blog
Learn, grow, and stay ahead in eLearning.
Documentation
Everything you need to build with Tutor LMS.
Videos
Learn visually with tutorials.
Release Notes
See what’s new in every update.
Partners
Explore our trusted Tutor LMS partners.
The Tutor LMS Course Builder provides an extensible system that allows third-party plugins to inject custom fields and content into predefined slots within the course builder interface. This system is inspired by the WordPress hook mechanism and allows developers to extend the Tutor LMS native course builder by adding custom fields within it.
How It Works
To begin, download the ‘Tutor LMS Custom Fields’ demo plugin. This plugin serves as a reference structure that you can update accordingly in order to add your customized settings.
Tutor LMS Custom Fields Directory Structure
Once you’ve downloaded the plugin, you’ll notice the following file structure:
tutor-lms-custom-fields/
│
├── custom-fields.js
└── tutor-lms-custom-fields.phpcustom-fields.js: This file contains JavaScript code to register custom fields in the course builder interface.tutor-lms-custom-fields.php: It contains PHP functions to enqueue scripts, save field data, and display field values.Custom fields are registered using JavaScript through the Tutor LMS course builder API. Create a custom-fields.js file with the following structure:
document.addEventListener("DOMContentLoaded", function () {
if (typeof Tutor !== "undefined" && Tutor.CourseBuilder) {
// Register a textarea field
Tutor.CourseBuilder.Basic.registerField("after_description", {
name: "seo_content",
type: "textarea",
label: "SEO Content",
placeholder: "Write here...",
priority: 20,
});
// Register a number field
Tutor.CourseBuilder.Curriculum.Lesson.registerField("bottom_of_sidebar", {
name: "lesson_duration",
type: "number",
label: "Lesson Duration (minutes)",
priority: 5,
});
}
});We’ve added two custom fields here. The first is a textarea field called SEO Content, located in the Basics tab. The second is a number field called Lesson Duration (minutes), placed at the bottom of the Lesson sidebar.
Here’s the SEO Content field in the Basics section:

Here’s the Lesson Duration field at the bottom of the Lesson sidebar:

You must enqueue your JavaScript file to display your custom fields in the course builder. To do this, create the tutor-lms-custom-fields.php file and add the following code:
This function hooks into tutor_after_course_builder_load to ensure the script is loaded only when the course builder is active, and it depends on the tutor-course-builder script.
When a course is saved, you need to capture and store the custom field values:
add_action('save_post_courses', 'tlcf_save_course_meta');
/**
* Save custom field data when course is saved
*
* @param int $post_id Course post ID.
*
* @return void
*/
function tlcf_save_course_meta( int $post_id ) {
$seo_content = sanitize_text_field( wp_unslash( $_POST['seo_content'] ) ?? '' );
if ( $seo_content ) {
update_post_meta( $post_id, 'tlcf_seo_content', $seo_content );
}
}You can specify the following things here:
add_action('save_post_courses', 'tlcf_save_course_meta'): This hooks into the course saving process.$_POST['seo_content']: Retrieves the value of the seo_content field.sanitize_textarea_field(): Sanitizes the input to prevent security vulnerabilities.update_post_meta(): Stores the sanitized value in the WordPress post meta table.To make custom field data available to the frontend or REST API, use the tutor_course_details_response filter:
add_filter('tutor_course_details_response', 'tlcf_display_custom_field_data');
/**
* Display custom field data in course details
*
* @param array $data Course data array.
*
* @return array Modified course data array with custom field
*/
function tlcf_display_custom_field_data( array $data ) {
$course_id = $data['ID'];
$seo_content = get_post_meta( $course_id, 'tlcf_seo_content', true );
if ( $seo_content ) {
$data['seo_content'] = $seo_content;
}
return $data;
}Here’s the explanation of this:
add_filter('tutor_course_details_response', 'tlcf_display_custom_field_data'): This filters the course details response, allowing you to add custom data.get_post_meta(): Retrieves the stored custom field values.$data['seo_content'] = $seo_content;: Adds the custom field value to the course details response.You can extend Tutor LMS Course Builder by using the following filter and action hooks.
apply_filters( 'tutor_course_details_response', array $course_data );
apply_filters( 'tutor_quiz_details_response', WP_Post $data, int $quiz_id );
apply_filters( 'tutor_assignment_details_response', array $post, int $assignment_id );
apply_filters( 'tutor_lesson_details_response', array $post, int $lesson_id );do_action( "save_post_courses", int $post_id, WP_Post $post, bool $update );
do_action( "save_post_lesson", int $post_id, WP_Post $post bool $update );
do_action( "save_post_tutor_assignments", int $post_id, WP_Post $post bool $update );
do_action( "save_post_tutor_quiz", int $post_id, WP_Post $post bool $update );When registering a field, you can specify:
| Property | Type | Description |
|---|---|---|
name | string | Unique name for the field (this field is required). |
type | text | text, number, password, textarea, select, radio, checkbox, switch, date, time, image, video, uploader, WPEditor |
label | string | Label for the field. |
placeholder | string | Placeholder text (optional). |
options | array | Required for select and radio fields.Example: [{ value: '1', label: 'Option 1' }]. |
priority | number | Determines order within the slot (lower values appear first). |
rules | object | Validation rules for React Hook Form. |
Here are the available slots where you can insert custom fields:
Basics Section
Curriculum Section
Additional Section
Q: How do I validate fields?
Use the rules property when registering a field:
Example 1: Required field validation
const requiredRule = () => ({
required: { value: true, message: 'This field is required' },
});Example 2: Max limit validation
const maxLimitRule = (maxLimit) => ({
validate: (value) => {
if (value && maxLimit < value.length) {
return `Maximum ${maxLimit} character supported`;
}
return undefined;
},
});By following this documentation, you can extend Tutor LMS with custom fields tailored to your specific needs.
Join the world’s #1 Tutor LMS community
By submitting your email, you agree to our Terms and Privacy Policy
Product
Solutions
Build, manage, and scale your eLearning business with the most powerful WordPress LMS — all in one place.
Crafted by Humans
© 2026 All Rights Reserved