H5P Guides

Set up H5P for Drupal 8

Download and install Drupal

Skip this step if you already have a running Drupal 8 installation.

Install the H5P module

1. Find the latest H5P module from the H5P project page on drupal.org:

2. Install the H5P module as you usually install a Drupal module. If you are new to Drupal modules, you can take a look at Drupal's installing modules guide.

You should see the following message:

3. Navigate to your site's module administration pages under the 'Extend' tab ('/admin/modules/'). Scroll to the section named "H5P" and enable the "H5P" and "H5P Editor" modules:

Add the H5P field to a Content Type

Drupal Content Types should not be confused with H5P Content Types. Drupal Content Types are simply different types of web pages such as articles or blog posts. H5P Content Types refer to the different types of H5P content such as Course Presentation or Memory Game.

You can add H5P content to Drupal Content Types by adding the H5P field. Let's add the H5P field to 'Basic Page', one of Drupal 8's default content types.

1. Navigate to the 'Structure' section ('/admin/structure') then click on 'Content Types':

2. Click on 'Manage Fields' for the 'Basic Page':

3. Then 'Add field':

4. Select H5P from the drop-down menu then press 'Save and continue':

You can specify the number of H5P fields you want to have in a content type. Let's choose 1 for now.

5. Lastly, click on the 'Manage Form display' tab and select 'H5P Editor' from the drop-down menu:

Let's check that the H5P field has been added. Click the 'Content' tab at the top (/admin/content), then the add content button:

Click on 'Basic Page' and you here you should be able to see the H5P Editor:

Install content types

Now your module is set up, and you can start creating H5P Content. After you click on "Add new" The H5P Hub will load - offering you a variety of content types to pick from.
Below you can see how to get new content types from the H5P Hub.

Here you can find Tutorials how to create content using different content types.

Roles and permissions

Depending on the framework used, access to H5P features may be controlled by defining the permissions for roles or users.

In Drupal, H5P has the following permissions available. They should be assigned users/roles as shown.

content writer site editor site administrator
create h5p Yes Yes Yes
edit own h5p Yes Yes Yes
delete own h5p Yes Yes Yes
edit any h5p No Yes Yes
delete any h5p No Yes Yes
update h5p libraries No Maybe* Yes
access all H5P results No Yes Yes
Access own H5P results Yes Yes Yes
Access h5p results for own content Yes Yes Yes
Create restricted H5P content types Maybe** Maybe** Yes

* The "update h5p libraries" permissions enables the user to upload H5Ps with updated library versions. Whether or not editors should have this access is up to site policy.

Updating old content to new versions can change their appearance and functionality significantly, preserving old content through library upgrades is always one of the main focuses of a library developer. Be aware of possible versioning and content upgrades issues when letting users upload altered H5P libraries.

** The "Create restricted H5P content types" permissions enables the user to create content types that users without this permission aren't allowed to create. Admins can configure what content types are restricted at admin/content/h5p. Who should have this access is up to the site policy.

Enable H5P shortcodes

H5P shortcodes are not yet possible in D8.

Enable result reports

By enabling Drupal's Views module a view will appear as a tab on each H5P node and on each user profile displaying basic result information.

Drupal 8's Views module allows us to display content from our database in a variety of ways. In our case, we are going to show two different displays, one for the results of each user and another for the results of each node.

To upload a pre-built view, click on the 'Configuration' tab then 'Configuration and synchronization'. Click on the 'Import' tab and select 'Single Item'. The full path is '/admin/config/development/configuration/single/import'. Note this sample view expects the H5P Field you created to be called 'H5P' as this will result in the machine name 'field_h5p' which is the machine name the view is seeking to match.

Select 'View' from the 'Configuration Type' dropdown then paste the following code (note that this is in YAML as opposed to HTML):

uuid: 3541d923-54a4-482b-87ac-4ac1d2617792
langcode: en
status: true
dependencies:
 config:
 - core.entity_view_mode.node.teaser
 module:
 - h5p
 - node
 - user
id: h5p_results
label: 'H5P results'
module: views
description: ''
tag: ''
base_table: node_field_data
base_field: nid
core: 8.x
display:
 default:
 display_plugin: default
 id: default
 display_title: Master
 position: 0
 display_options:
 access:
 type: perm
 options:
 perm: 'access content'
 cache:
 type: none
 options: { }
 query:
 type: views_query
 options:
 disable_sql_rewrite: false
 distinct: false
 replica: false
 query_comment: ''
 query_tags: { }
 exposed_form:
 type: basic
 options:
 submit_button: Apply
 reset_button: false
 reset_button_label: Reset
 exposed_sorts_label: 'Sort by'
 expose_sort_order: true
 sort_asc_label: Asc
 sort_desc_label: Desc
 pager:
 type: mini
 options:
 items_per_page: 10
 offset: 0
 id: 0
 total_pages: null
 expose:
 items_per_page: false
 items_per_page_label: 'Items per page'
 items_per_page_options: '5, 10, 25, 50'
 items_per_page_options_all: false
 items_per_page_options_all_label: '- All -'
 offset: false
 offset_label: Offset
 tags:
 previous: ‹‹
 next: ››
 style:
 type: table
 options:
 grouping: { }
 row_class: ''
 default_row_class: true
 override: true
 sticky: false
 caption: ''
 summary: ''
 description: ''
 columns:
 title: title
 info:
 title:
 sortable: false
 default_sort_order: asc
 align: ''
 separator: ''
 empty_column: false
 responsive: ''
 default: '-1'
 empty_table: false
 row:
 type: 'entity:node'
 options:
 view_mode: teaser
 fields:
 title:
 id: title
 table: node_field_data
 field: title
 entity_type: node
 entity_field: title
 label: ''
 alter:
 alter_text: false
 make_link: false
 absolute: false
 trim: false
 word_boundary: false
 ellipsis: false
 strip_tags: false
 html: false
 hide_empty: false
 empty_zero: false
 settings:
 link_to_entity: true
 plugin_id: field
 relationship: none
 group_type: group
 admin_label: ''
 exclude: false
 element_type: ''
 element_class: ''
 element_label_type: ''
 element_label_class: ''
 element_label_colon: true
 element_wrapper_type: ''
 element_wrapper_class: ''
 element_default_classes: true
 empty: ''
 hide_alter_empty: true
 click_sort_column: value
 type: string
 group_column: value
 group_columns: { }
 group_rows: true
 delta_limit: 0
 delta_offset: 0
 delta_reversed: false
 delta_first_last: false
 multi_type: separator
 separator: ', '
 field_api_classes: false
 name:
 id: name
 table: users_field_data
 field: name
 relationship: uid
 group_type: group
 admin_label: ''
 label: Name
 exclude: false
 alter:
 alter_text: false
 text: ''
 make_link: false
 path: ''
 absolute: false
 external: false
 replace_spaces: false
 path_case: none
 trim_whitespace: false
 alt: ''
 rel: ''
 link_class: ''
 prefix: ''
 suffix: ''
 target: ''
 nl2br: false
 max_length: 0
 word_boundary: true
 ellipsis: true
 more_link: false
 more_link_text: ''
 more_link_path: ''
 strip_tags: false
 trim: false
 preserve_tags: ''
 html: false
 element_type: ''
 element_class: ''
 element_label_type: ''
 element_label_class: ''
 element_label_colon: true
 element_wrapper_type: ''
 element_wrapper_class: ''
 element_default_classes: true
 empty: ''
 hide_empty: false
 empty_zero: false
 hide_alter_empty: true
 click_sort_column: value
 type: user_name
 settings:
 link_to_entity: true
 group_column: value
 group_columns: { }
 group_rows: true
 delta_limit: 0
 delta_offset: 0
 delta_reversed: false
 delta_first_last: false
 multi_type: separator
 separator: ', '
 field_api_classes: false
 entity_type: user
 entity_field: name
 plugin_id: field
 started:
 id: started
 table: h5p_points
 field: started
 relationship: field_h5p_h5p_content_id
 group_type: group
 admin_label: ''
 label: Started
 exclude: false
 alter:
 alter_text: false
 text: ''
 make_link: false
 path: ''
 absolute: false
 external: false
 replace_spaces: false
 path_case: none
 trim_whitespace: false
 alt: ''
 rel: ''
 link_class: ''
 prefix: ''
 suffix: ''
 target: ''
 nl2br: false
 max_length: 0
 word_boundary: true
 ellipsis: true
 more_link: false
 more_link_text: ''
 more_link_path: ''
 strip_tags: false
 trim: false
 preserve_tags: ''
 html: false
 element_type: ''
 element_class: ''
 element_label_type: ''
 element_label_class: ''
 element_label_colon: true
 element_wrapper_type: ''
 element_wrapper_class: ''
 element_default_classes: true
 empty: ''
 hide_empty: false
 empty_zero: false
 hide_alter_empty: true
 date_format: fallback
 custom_date_format: ''
 timezone: ''
 plugin_id: date
 finished:
 id: finished
 table: h5p_points
 field: finished
 relationship: field_h5p_h5p_content_id
 group_type: group
 admin_label: ''
 label: Finished
 exclude: false
 alter:
 alter_text: false
 text: ''
 make_link: false
 path: ''
 absolute: false
 external: false
 replace_spaces: false
 path_case: none
 trim_whitespace: false
 alt: ''
 rel: ''
 link_class: ''
 prefix: ''
 suffix: ''
 target: ''
 nl2br: false
 max_length: 0
 word_boundary: true
 ellipsis: true
 more_link: false
 more_link_text: ''
 more_link_path: ''
 strip_tags: false
 trim: false
 preserve_tags: ''
 html: false
 element_type: ''
 element_class: ''
 element_label_type: ''
 element_label_class: ''
 element_label_colon: true
 element_wrapper_type: ''
 element_wrapper_class: ''
 element_default_classes: true
 empty: ''
 hide_empty: false
 empty_zero: false
 hide_alter_empty: true
 date_format: fallback
 custom_date_format: ''
 timezone: ''
 plugin_id: date
 points:
 id: points
 table: h5p_points
 field: points
 relationship: field_h5p_h5p_content_id
 group_type: group
 admin_label: ''
 label: Points
 exclude: false
 alter:
 alter_text: false
 text: ''
 make_link: false
 path: ''
 absolute: false
 external: false
 replace_spaces: false
 path_case: none
 trim_whitespace: false
 alt: ''
 rel: ''
 link_class: ''
 prefix: ''
 suffix: ''
 target: ''
 nl2br: false
 max_length: 0
 word_boundary: true
 ellipsis: true
 more_link: false
 more_link_text: ''
 more_link_path: ''
 strip_tags: false
 trim: false
 preserve_tags: ''
 html: false
 element_type: ''
 element_class: ''
 element_label_type: ''
 element_label_class: ''
 element_label_colon: true
 element_wrapper_type: ''
 element_wrapper_class: ''
 element_default_classes: true
 empty: ''
 hide_empty: false
 empty_zero: false
 hide_alter_empty: true
 set_precision: false
 precision: 0
 decimal: .
 separator: ','
 format_plural: false
 format_plural_string: "1\x03@count"
 prefix: ''
 suffix: ''
 plugin_id: numeric
 max_points:
 id: max_points
 table: h5p_points
 field: max_points
 relationship: field_h5p_h5p_content_id
 group_type: group
 admin_label: ''
 label: 'Max points'
 exclude: false
 alter:
 alter_text: false
 text: ''
 make_link: false
 path: ''
 absolute: false
 external: false
 replace_spaces: false
 path_case: none
 trim_whitespace: false
 alt: ''
 rel: ''
 link_class: ''
 prefix: ''
 suffix: ''
 target: ''
 nl2br: false
 max_length: 0
 word_boundary: true
 ellipsis: true
 more_link: false
 more_link_text: ''
 more_link_path: ''
 strip_tags: false
 trim: false
 preserve_tags: ''
 html: false
 element_type: ''
 element_class: ''
 element_label_type: ''
 element_label_class: ''
 element_label_colon: true
 element_wrapper_type: ''
 element_wrapper_class: ''
 element_default_classes: true
 empty: ''
 hide_empty: false
 empty_zero: false
 hide_alter_empty: true
 set_precision: false
 precision: 0
 decimal: .
 separator: ','
 format_plural: false
 format_plural_string: "1\x03@count"
 prefix: ''
 suffix: ''
 plugin_id: numeric
 filters:
 status:
 value: '1'
 table: node_field_data
 field: status
 plugin_id: boolean
 entity_type: node
 entity_field: status
 id: status
 expose:
 operator: ''
 group: 1
 uid_current:
 id: uid_current
 table: users
 field: uid_current
 entity_type: user
 plugin_id: user_current
 relationship: uid
 sorts:
 created:
 id: created
 table: node_field_data
 field: created
 order: DESC
 entity_type: node
 entity_field: created
 plugin_id: date
 relationship: none
 group_type: group
 admin_label: ''
 exposed: false
 expose:
 label: ''
 granularity: second
 title: 'H5P results'
 header: { }
 footer: { }
 empty: { }
 relationships:
 field_h5p_h5p_content_id:
 id: field_h5p_h5p_content_id
 table: node__field_h5p
 field: field_h5p_h5p_content_id
 relationship: none
 group_type: group
 admin_label: 'H5P from field_h5p'
 required: false
 plugin_id: standard
 uid:
 id: uid
 table: h5p_points
 field: uid
 relationship: field_h5p_h5p_content_id
 group_type: group
 admin_label: 'H5P user points'
 required: false
 plugin_id: standard
 arguments: { }
 display_extenders: { }
 cache_metadata:
 max-age: 0
 contexts:
 - 'languages:language_content'
 - 'languages:language_interface'
 - url.query_args
 - user
 - 'user.node_grants:view'
 - user.permissions
 tags: { }
 page_1:
 display_plugin: page
 id: page_1
 display_title: 'User results'
 position: 1
 display_options:
 display_extenders: { }
 path: user-results
 filters:
 status:
 value: '1'
 table: node_field_data
 field: status
 plugin_id: boolean
 entity_type: node
 entity_field: status
 id: status
 expose:
 operator: ''
 group: 1
 uid_current:
 id: uid_current
 table: users
 field: uid_current
 relationship: uid
 group_type: group
 admin_label: ''
 operator: '='
 value: '1'
 group: 1
 exposed: false
 expose:
 operator_id: ''
 label: ''
 description: ''
 use_operator: false
 operator: ''
 identifier: ''
 required: false
 remember: false
 multiple: false
 remember_roles:
 authenticated: authenticated
 is_grouped: false
 group_info:
 label: ''
 description: ''
 identifier: ''
 optional: true
 widget: select
 multiple: false
 remember: false
 default_group: All
 default_group_multiple: { }
 group_items: { }
 entity_type: user
 plugin_id: user_current
 defaults:
 filters: false
 filter_groups: false
 filter_groups:
 operator: AND
 groups:
 1: AND
 display_description: ''
 cache_metadata:
 max-age: 0
 contexts:
 - 'languages:language_content'
 - 'languages:language_interface'
 - url.query_args
 - user
 - 'user.node_grants:view'
 - user.permissions
 tags: { }
 page_2:
 display_plugin: page
 id: page_2
 display_title: 'Node results'
 position: 2
 display_options:
 display_extenders: { }
 path: node/%node/results
 filters:
 status:
 value: '1'
 table: node_field_data
 field: status
 plugin_id: boolean
 entity_type: node
 entity_field: status
 id: status
 expose:
 operator: ''
 group: 1
 defaults:
 filters: false
 filter_groups: false
 arguments: false
 filter_groups:
 operator: AND
 groups:
 1: AND
 arguments:
 nid:
 id: nid
 table: node_field_data
 field: nid
 relationship: none
 group_type: group
 admin_label: ''
 default_action: default
 exception:
 value: all
 title_enable: false
 title: All
 title_enable: false
 title: ''
 default_argument_type: node
 default_argument_options: { }
 default_argument_skip_url: false
 summary_options:
 base_path: ''
 count: true
 items_per_page: 25
 override: false
 summary:
 sort_order: asc
 number_of_records: 0
 format: default_summary
 specify_validation: false
 validate:
 type: none
 fail: 'not found'
 validate_options: { }
 break_phrase: false
 not: false
 entity_type: node
 entity_field: nid
 plugin_id: node_nid
 display_description: ''
 cache_metadata:
 max-age: 0
 contexts:
 - 'languages:language_content'
 - 'languages:language_interface'
 - url
 - url.query_args
 - 'user.node_grants:view'
 - user.permissions
 tags: { }

Go to 'Structure' then 'Views' to see our newly created 'H5P results' view:

Press 'Edit' to see how the H5P results View is defined.

The sample View comes with two displays, one for User Results and another for Node results. For the purposes of this tutorial, we are just going to show the User results display.

Navigate to the path specified, we will see that the H5P results display is as we expect: