WP_Script_Modules::print_script_module_data()

In this article

Print data associated with Script Modules.

Description

The data will be embedded in the page HTML and can be read by Script Modules on page load.

Source

public function print_script_module_data(): void {
	$modules = array();
	foreach ( array_keys( $this->get_marked_for_enqueue() ) as $id ) {
		if ( '@wordpress/a11y' === $id ) {
			$this->a11y_available = true;
		}
		$modules[ $id ] = true;
	}
	foreach ( array_keys( $this->get_import_map()['imports'] ) as $id ) {
		if ( '@wordpress/a11y' === $id ) {
			$this->a11y_available = true;
		}
		$modules[ $id ] = true;
	}

	foreach ( array_keys( $modules ) as $module_id ) {
		/**
		 * Filters data associated with a given Script Module.
		 *
		 * Script Modules may require data that is required for initialization or is essential
		 * to have immediately available on page load. These are suitable use cases for
		 * this data.
		 *
		 * The dynamic portion of the hook name, `$module_id`, refers to the Script Module ID
		 * that the data is associated with.
		 *
		 * This is best suited to pass essential data that must be available to the module for
		 * initialization or immediately on page load. It does not replace the REST API or
		 * fetching data from the client.
		 *
		 * @example
		 *   add_filter(
		 *     'script_module_data_MyScriptModuleID',
		 *     function ( array $data ): array {
		 *       $data['script-needs-this-data'] = 'ok';
		 *       return $data;
		 *     }
		 *   );
		 *
		 * If the filter returns no data (an empty array), nothing will be embedded in the page.
		 *
		 * The data for a given Script Module, if provided, will be JSON serialized in a script
		 * tag with an ID of the form `wp-script-module-data-{$module_id}`.
		 *
		 * The data can be read on the client with a pattern like this:
		 *
		 * @example
		 *   const dataContainer = document.getElementById( 'wp-script-module-data-MyScriptModuleID' );
		 *   let data = {};
		 *   if ( dataContainer ) {
		 *     try {
		 *       data = JSON.parse( dataContainer.textContent );
		 *     } catch {}
		 *   }
		 *   initMyScriptModuleWithData( data );
		 *
		 * @since 6.7.0
		 *
		 * @param array $data The data associated with the Script Module.
		 */
		$data = apply_filters( "script_module_data_{$module_id}", array() );

		if ( is_array( $data ) && array() !== $data ) {
			/*
			 * This data will be printed as JSON inside a script tag like this:
			 *   <script type="application/json"></script>
			 *
			 * A script tag must be closed by a sequence beginning with `</`. It's impossible to
			 * close a script tag without using `<`. We ensure that `<` is escaped and `/` can
			 * remain unescaped, so `</script>` will be printed as `\u003C/script\u00E3`.
			 *
			 *   - JSON_HEX_TAG: All < and > are converted to \u003C and \u003E.
			 *   - JSON_UNESCAPED_SLASHES: Don't escape /.
			 *
			 * If the page will use UTF-8 encoding, it's safe to print unescaped unicode:
			 *
			 *   - JSON_UNESCAPED_UNICODE: Encode multibyte Unicode characters literally (instead of as `\uXXXX`).
			 *   - JSON_UNESCAPED_LINE_TERMINATORS: The line terminators are kept unescaped when
			 *     JSON_UNESCAPED_UNICODE is supplied. It uses the same behaviour as it was
			 *     before PHP 7.1 without this constant. Available as of PHP 7.1.0.
			 *
			 * The JSON specification requires encoding in UTF-8, so if the generated HTML page
			 * is not encoded in UTF-8 then it's not safe to include those literals. They must
			 * be escaped to avoid encoding issues.
			 *
			 * @see https://www.rfc-editor.org/rfc/rfc8259.html for details on encoding requirements.
			 * @see https://www.php.net/manual/en/json.constants.php for details on these constants.
			 * @see https://html.spec.whatwg.org/#script-data-state for details on script tag parsing.
			 */
			$json_encode_flags = JSON_HEX_TAG | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS;
			if ( ! is_utf8_charset() ) {
				$json_encode_flags = JSON_HEX_TAG | JSON_UNESCAPED_SLASHES;
			}

			wp_print_inline_script_tag(
				wp_json_encode(
					$data,
					$json_encode_flags
				),
				array(
					'type' => 'application/json',
					'id'   => "wp-script-module-data-{$module_id}",
				)
			);
		}
	}
}

Hooks

apply_filters( “script_module_data_{$module_id}”, array $data )

Filters data associated with a given Script Module.

Changelog

VersionDescription
6.7.0Introduced.

User Contributed Notes

You must log in before being able to contribute a note or feedback.