MeteorCommunity/discussions

Allow apps to specify extra body to be added to server side HTML output

mitar opened this issue · 1 comments

While waiting for "perfect" solution, I think that Meteor should provide some way to add extra HTML output to the server-side body, dynamically, based on each request.

I made a pull request which allows simple way of adding output to the server side HTML output. Additionally, it moves loading of (possibly big) JavaScript to the end of the body, so that body is displayed first in the browser, and then JavaScript is loaded. This does not change much when this API is not used, but changes usefulness a lot, when it is.

I completely agree, it should be rather simple to change the initial HTML of a meteor app.

I wrote a simple script using the meteorhacks:inject-initial package. This one adds a CSS file a little HTML and moves the script tags to the end of the body.
You can also find this on my blog http://frozeman.de/blog/2015/01/meteor-platform-packages-and-loading-screens/

// inject HEAD scripts
Inject.rawHead('loadingScripts', '  <link class="inject-loading-container" rel="stylesheet" href="/loading.css">');

// inject BODY HTML
Inject.rawBody('loadingBody', '  <div class="inject-loading-container">'+ "\n" +
                                '    <h1>'+ "\n" +
                                '      Loading...'+ "\n" +
                                '    </h1>'+ "\n" +
                                '  </div>');

/**
Moves all javascripts to the end of the body, so we can inject the loading screen

*/
Inject.rawModHtml('moveScriptsToBottom', function(html) {
    // get all scripts
    var scripts = html.match(/<script type="text\/javascript" src.*"><\/script>\n/g);

    // if found
    if(!_.isEmpty(scripts)) {
        // remove all scripts
        html = html.replace(/<script type="text\/javascript" src.*"><\/script>\n/g, '');
        // add scripts to the bottom
        html = html.replace(/<\/body>/, scripts.join('') + '\n</body>');
        return html.replace(/[\n]+/g,"\n").replace(/ +/g,' ');

    // otherwise pass the raw html through
    } else {
        return html.replace(/[\n]+/g,"\n").replace(/ +/g,' ');
    }
});

You just need then to remove the loading HTML and CSS when the app is started:

Meteor.startup(function() {

    // remove the loading box
    $('.inject-loading-container').remove();

});