H5P Content not displaying on WordPress website

I have a WordPress website and use Tutor LMS. I am using H5P presentations as content.

When you start a course, the first lesson appears, but when you click on any other lesson in the lesson list, the content does not appear. However, if you refresh the page, the content appears. The Tutor LMS support people seem to think it's a problem with the H5P shortcodes. I have entered my website in an international competition and I am desparate to ensure it functions correctly. Are you able to help at all?

Technical details

Website: https://mastervocabulary.com/

  1. Content type: H5P presentations
  2. Device: Desktop
  3. Wordpress: 5.7
  4. H5P: 1.15.0
  5. PHP 7.4.1
  6. Browsers used: Chrome, Safari, Microsoft Edge

Browser console error

otacke's picture

Hi Miles!

Those error messages don't have anything to do with H5P. I am not familiar with how TutorLMS loads pages or content.

It could be a problem with "lazy loading" mechanisms that change the order/timing for loading files - not necessarily caused by TutorLMS, but potentially by some other plugin.

It could also be a missing resize if TutorLMS loads content but hides it first (e. g. in different tabs). In that case, a workaround is to use https://wordpress.org/plugins/snordians-h5p-resize-pulse/ but a proper solution would require to either add a line of code to TutorLMS or to write a custom plugin.



otacke's picture

Hi Miles!

I now had a look at TutorLMS. My previous ideas won't help. It may be a little technical, but anyway ...

When a TutorLMS lesson is (re-)loaded, then

  1. H5P loads required scripts and lurks in the background until the page/post is "ready",
  2. at some point, WordPress is requested by TutorLMS to setup a post which requires to replace shortcodes (https://plugins.trac.wordpress.org/browser/tutor/tags/1.8.6/classes/Lesson.php#L346),
  3. H5P replaces the shortcode with a basic frame for the iframe and updates the settings, but does not yet load the content (https://github.com/h5p/h5p-wordpress-plugin/blob/release/public/class-h5p-plugin.php#L984-L1017),
  4. WordPress may do other things,
  5. when the page/post is loaded, H5P replaces the iframe frame with the actual content and stops lurking (https://github.com/h5p/h5p-php-library/blob/7bc8666f309220a0eb93bca49aaa741bb013b26a/js/h5p.js#L2680-L2831).

Now, when you change the lesson in TutorLMS via the lesson list (not when you click on previous/next), TutorLMS does not reload the whole page but only requests WordPress to set up the post, thus to replace the shortcode for some other H5P content (in 2)), but H5P is not lurking in the background anymore. It replaces the shortcode with the iframe frame and updates the settings, but never actually sets the required settings for the new content and never tries to replace the frame with the content in 5).

So, although it's quite clear what needs to happen, I am not sure if it will.

On the one hand, the H5P core team could change how H5P content is loaded and rendered or , but I am not sure how much work that would be - and the H5P core team might rightfully ask why they should take extra care of TutorLMS ...

On the other hand, the TutorLMS team could add some extra handler for H5P content (when they let WordPress set up the post), load/reference the required resources themselves and run the H5P.init function - but they could rightfully ask why they should take extra care of H5P ...

A quick hack (that may have side effects that I have not checked for), is to add one line of code to TutorLMS:

  1. Make a backup of your WordPress instance!
  2. Open wp-content/plugins/tutor/classes/Lesson.php (in the WordPress plugin editor if you don't have other access to the server).
  3. Locate the function tutor_render_lesson_content and therein find the lines 
    and replace them with 
    do_action( 'wp_footer' );
    and don't forget to save.

That will trigger H5P to add the settings that it has updated to the page and also trigger the "document ready" handler again that will tell H5P to render the contents.

Note however, that your changes will be overwritten whenever you update the TutorLMS plugin.


sekander's picture

Hello Oliver,

Thank you so much for taking a kind look at Tutor LMS plugin source code. As far I understand, the way you have recommended to edit the source code of Tutor LMS is not a good way to modify things.

So, I was wondering if we could find a way to add the H5P compatibility officially in a non-invasive way. Do you think it is possible for us to work together to add the H5P compatibility?

My email address is sekander at themeum dot com. We have very limited resources right now. So, I am not sure if we can invest some resources very soon but I want to give this a try and see how far we can go. We have around 22 emails requesting the H5P compatibility.

otacke's picture

Hi sekander!

I am sorry, but I am in no position to decide anything in that regard. Either the H5P core team will have to help you or the TutorLMS team.


sekander's picture


Can you please connect me with the Core team?

BV52's picture

Hi sekander,

I suggest that you send an email through the contact form. So that I can send the request to the developers. There is no guarantee that changes will be made since it looks like this a specific only to how Tutor LMS "loads" lessons.


Does anyone have any updates on this issue? I would really love to use H5P with Tutor LMS.

You can use an H5P embed code as the embedded video source -- which loads it -- but it cuts off the bottom for some reason.. 

Edit Line 379 in h5p.js file (wp-content/plugins/h5p/h5p-php-library/js/h5p.js) and replace with:

  // Insert H5Ps that should be in iframes.
  H5P.jQuery('iframe.h5p-iframe:not(.h5p-initialized)', target).each(function () {
    var contentId = H5P.jQuery(this).addClass('h5p-initialized').data('content-id');
    var self = this;
      var doc = self.contentDocument;
      doc.write('<!doctype html><html class="h5p-iframe"><head>' + H5P.getHeadTags(contentId) + '</head><body><div class="h5p-content" data-content-id="' + contentId + '"/></body></html>');


After this it should work in mobile Safari and Desktop.