Static HTML and Meteor


#1

I don’t think the subject really explains what I am looking for, so here is a better explanation.

Someone developed a web-site with a lot of static content. On some pages there needs to be data driven components (dropdowns, search).

I am trying to figure out how I can develop the data driven parts in meteor without having to re-deploy the entire application when some static HTML changes.

Is there a way to integrate meteor with a static site?


#2

I tried this recently, but every page fell on the same page like a single page application. So I had to at least integrate a router to get stuff on separate pages.

Knowing the load order helped when I tried it out https://guide.meteor.com/structure.html#load-order

There may be a better way to do it for your context though.


#3

I found the perfect package for this: ows-meteor-client-side. With this embedded in the static web-site, I can connect to a Meteor back-end and get collections, call methods, it is perfect.

In my first little test I created a widget under public/widgets/test.js in my meteor project (for this example I also copied the meteor-client-side.js into public/widgets, but that could be hosted with the static web site as well).

Here is what test.js looks like

var METEOR_PROJECT = 'http://localhost:3000';
var debug = document.currentScript.getAttribute('debug');
var widget = document.currentScript.getAttribute('widget');
//
// needed to close the connection when navigating away from the static HTML page
//
window.onbeforeunload = function () {
    Meteor.disconnect();
    return undefined;
}

__meteor_runtime_config__ = {
    meteorEnv: {},
    DDP_DEFAULT_CONNECTION_URL: METEOR_PROJECT,
};

$.getScript(METEOR_PROJECT+'/widgets/meteor-client-side.bundle.min.js',function(){
    if(debug) console.log('meteor-client-side.bundle loaded, looking for '+widgetId);
    // now that client side is loaded I have access to Meteor and Mongo
    var Pages = new Mongo.Collection('pages');

    var $widget = $(widget);
    // check for the widgetId in the DOM
    if($widget.size()>0) {
        if(debug) console.log('subscribing');
        Meteor.subscribe('pages.all', function(){
            if(debug) console.log('pages subscribed '+Pages.find().count());
            // now we can add the collection results to our DOM using jQuery
            Pages.find().observeChanges({
                added: function (id, fields) {
                    $widget.append('<li id="'+id+'">'+fields.title+'</li>');
                },
                changed: function (id, fields) {
                    $('#'+id).html(fields.title);
                },
                removed: function (id) {
                    $('#'+id).remove();
                }
            });
        });
    } else {
        console.error(widget ? widget+' does not exist in the DOM' : 'please specify attribute widgetId');
    }
});

In my static HTML all I need to do is add the widget I want the Meteor content to be inserted into and call my widget

<div id="widget"><ol id="pages"></ol></div>
<script 
 src="http://localhost:3000/widgets/test.js" 
 debug=true 
 widget="#pages"
 defer="true"
>alert('test.js!')</script>

And voila, reactive content in a static web page.


#4

Researching some more I found meteor-webpack-client, and meteor-client-bundler also looks very interesting.