diff --git a/core/core.libraries.yml b/core/core.libraries.yml
index dc714de..f19530b 100644
--- a/core/core.libraries.yml
+++ b/core/core.libraries.yml
@@ -52,6 +52,8 @@ drupal:
 
 drupalSettings:
   version: VERSION
+  js:
+    misc/drupalSettings.js: { weight: -18 }
   drupalSettings:
     # These placeholder values will be set by system_js_settings_alter().
     path:
diff --git a/core/lib/Drupal/Core/Asset/JsCollectionRenderer.php b/core/lib/Drupal/Core/Asset/JsCollectionRenderer.php
index 7db84ab..3647317 100644
--- a/core/lib/Drupal/Core/Asset/JsCollectionRenderer.php
+++ b/core/lib/Drupal/Core/Asset/JsCollectionRenderer.php
@@ -50,12 +50,6 @@ public function render(array $js_assets) {
     // query-string instead, to enforce reload on every page request.
     $default_query_string = $this->state->get('system.css_js_query_string') ?: '0';
 
-    // For inline JavaScript to validate as XHTML, all JavaScript containing
-    // XHTML needs to be wrapped in CDATA. To make that backwards compatible
-    // with HTML 4, we need to comment out the CDATA-tag.
-    $embed_prefix = "\n<!--//--><![CDATA[//><!--\n";
-    $embed_suffix = "\n//--><!]]>\n";
-
     // Defaults for each SCRIPT element.
     $element_defaults = array(
       '#type' => 'html_tag',
@@ -72,9 +66,13 @@ public function render(array $js_assets) {
       // Element properties that depend on item type.
       switch ($js_asset['type']) {
         case 'setting':
-          $element['#value_prefix'] = $embed_prefix;
-          $element['#value'] = 'var drupalSettings = ' . Json::encode($js_asset['data']) . ";";
-          $element['#value_suffix'] = $embed_suffix;
+          $element['#attributes'] = array(
+            // This type attribute prevents this from being parsed as an
+            // inline script.
+            'type' => 'application/json',
+            'data-drupal-selector' => 'drupal-settings-json',
+          );
+          $element['#value'] =  Json::encode($js_asset['data']);
           break;
 
         case 'file':
diff --git a/core/misc/drupal.js b/core/misc/drupal.js
index 75f85bb..8ef8167 100644
--- a/core/misc/drupal.js
+++ b/core/misc/drupal.js
@@ -12,14 +12,6 @@
  */
 
 /**
- * Variable generated by Drupal with all the configuration created from PHP.
- *
- * @global
- *
- * @var {object} drupalSettings
- */
-
-/**
  * Variable generated by Drupal that holds all translated strings from PHP.
  *
  * @global
diff --git a/core/misc/drupalSettings.js b/core/misc/drupalSettings.js
new file mode 100644
index 0000000..ea2ef57
--- /dev/null
+++ b/core/misc/drupalSettings.js
@@ -0,0 +1,21 @@
+/**
+ * @file
+ * Parse and initialize drupalSettings global object.
+ */
+
+(function () {
+
+  "use strict";
+
+  var settingsElement = document.querySelector('[data-drupal-selector="drupal-settings-json"]');
+
+  /**
+   * Variable generated by Drupal with all the configuration created from PHP.
+   *
+   * @global
+   *
+   * @type {object}
+   */
+  window.drupalSettings = JSON.parse(settingsElement.textContent);
+
+})();
