FIX: Ember CLI was losing some preloaded data (#13406)

FIX: Ember CLI was losing some preloaded data (#13406)

The bootstrap.json contains most preloaded information but some routes provide extra information, such as invites.

This fixes the issue by having the preload request pass on the preloaded data from the source page, which is then merged with the bootstrap’s preloaded data for the final HTML payload.

diff --git a/app/assets/javascripts/discourse/lib/bootstrap-json/index.js b/app/assets/javascripts/discourse/lib/bootstrap-json/index.js
index f8dc77a..7c78d2d 100644
--- a/app/assets/javascripts/discourse/lib/bootstrap-json/index.js
+++ b/app/assets/javascripts/discourse/lib/bootstrap-json/index.js
@@ -132,10 +132,10 @@ function preloaded(buffer, bootstrap) {
 const BUILDERS = {
   "html-tag": htmlTag,
   "before-script-load": beforeScriptLoad,
-  head: head,
-  body: body,
+  head,
+  body,
   "hidden-login-form": hiddenLoginForm,
-  preloaded: preloaded,
+  preloaded,
   "body-footer": bodyFooter,
   "locale-script": localeScript,
 };
@@ -148,14 +148,20 @@ function replaceIn(bootstrap, template, id, headers) {
   return template.replace(`<bootstrap-content key="${id}">`, contents);
 }
 
-function applyBootstrap(bootstrap, template, headers) {
+async function applyBootstrap(bootstrap, template, response) {
+  // If our initial page added some preload data let's not lose that.
+  let json = await response.json();
+  if (json && json.preloaded) {
+    bootstrap.preloaded = Object.assign(json.preloaded, bootstrap.preloaded);
+  }
+
   Object.keys(BUILDERS).forEach((id) => {
-    template = replaceIn(bootstrap, template, id, headers);
+    template = replaceIn(bootstrap, template, id, response);
   });
   return template;
 }
 
-function buildFromBootstrap(assetPath, proxy, baseURL, req, headers) {
+function buildFromBootstrap(assetPath, proxy, baseURL, req, response) {
   // eslint-disable-next-line
   return new Promise((resolve, reject) => {
     fs.readFile(
@@ -170,8 +176,9 @@ function buildFromBootstrap(assetPath, proxy, baseURL, req, headers) {
 
         getJSON(url, null, req.headers)
           .then((json) => {
-            resolve(applyBootstrap(json.bootstrap, template, headers));
+            return applyBootstrap(json.bootstrap, template, response);
           })
+          .then(resolve)
           .catch((e) => {
             reject(
               `Could not get ${proxy}${baseURL}bootstrap.json\n\n${e.toString()}`
@@ -203,16 +210,17 @@ async function handleRequest(assetPath, proxy, baseURL, req, res) {
         let get = bent("GET", [200, 301, 302, 303, 307, 308, 404, 403, 500]);
         let response = await get(url, null, req.headers);
         res.set(response.headers);
+        res.set("content-type", "text/html");
         if (response.headers["x-discourse-bootstrap-required"] === "true") {
           req.headers["X-Discourse-Asset-Path"] = req.path;
-          let json = await buildFromBootstrap(
+          let html = await buildFromBootstrap(
             assetPath,
             proxy,
             baseURL,
             req,
-            response.headers
+            response
           );
-          return res.send(json);
+          return res.send(html);
         }
         res.status(response.status);
         res.send(await response.text());
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 5d16eb2..7ec3091 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -322,7 +322,9 @@ class ApplicationController < ActionController::Base
   end
 
   def send_ember_cli_bootstrap
-    head 200, content_type: "text/html", "X-Discourse-Bootstrap-Required": true
+    response.headers['X-Discourse-Bootstrap-Required'] = true
+    response.headers['Content-Type'] = "application/json"
+    render json: { preloaded: @preloaded }
   end
 
   # If a controller requires a plugin, it will raise an exception if that plugin is

GitHub sha: 651b8a23b8c619cf23468ca38b9fed63d597d9c3

1 Like

This commit appears in #13406 which was approved by riking. It was merged by eviltrout.