Files
meteor/packages/server-render/server.js
Ben Newman fb73388ce3 Make server-render API more flexible and isomorph-ish.
Render callbacks can now inject HTML content into multiple different
elements, and may also append content to the <head> or <body> elements, on
both the client and the server.

This new API was inspired by trying to use the styled-components npm
package on the server, which involves not only rendering and injecting
static HTML somewhere in the <body>, but also appending the resulting
<style> tag(s) into the <head>:

  import { onPageLoad } from "meteor/server-render";
  import { renderToString } from "react-dom/server";
  import { ServerStyleSheet } from "styled-components";

  onPageLoad(sink => {
    const sheet = new ServerStyleSheet();
    const html = renderToString(sheet.collectStyles(
      <App location={sink.request.url} />
    ));

    sink.renderIntoElementById("app", html);
    sink.appendToHead(sheet.getStyleTags());
  });

Note that the server-render package now exports an onPageLoad function,
rather than the old renderIntoElementById function. The functionality of
renderIntoElementById is now exposed by the {Client,Server}Sink API.

I say the client-side version of this API is 'isomorphish' to the
server-side version, because ClientSink methods can accept DOM nodes in
addition to raw HTML strings, whereas DOM nodes don't really make sense on
the server.
2017-06-29 15:08:32 -04:00

33 lines
773 B
JavaScript

import { Meteor } from "meteor/meteor";
import "./server-register.js";
const startupPromise = new Promise(Meteor.startup);
const pageLoadCallbacks = new Set;
export function onPageLoad(callback) {
if (typeof callback === "function") {
pageLoadCallbacks.add(callback);
}
// Return the callback so that it can be more easily removed later.
return callback;
}
onPageLoad.remove = function (callback) {
pageLoadCallbacks.delete(callback);
};
onPageLoad.clear = function () {
pageLoadCallbacks.clear();
};
onPageLoad.chain = function (handler) {
return startupPromise.then(() => {
let promise = Promise.resolve();
pageLoadCallbacks.forEach(callback => {
promise = promise.then(() => handler(callback));
});
return promise;
});
};