How to build embeddable apps with Ember.js?

A friend of mine is considering using Ember.js to build an app that would need to be embeddable into html pages.

You might want to look into oasis.js for this? http://oasisjs.com/

Oasis looks more like messaging rather than packaging. Are you familiar with it?

I haven’t used it personally, but I saw a presentation on it at the ember nyc meetup. The impression I was given was that you could use it to run sandboxed applications. However, I think it’s possible to run multiple ember apps within one page, you’ll just need to set the rootElement on the ember application:

window.App = Ember.Application.create({
  rootElement: '#ember-app'
});

I haven’t done this myself, but I think it should be possible, just make sure to use different namespaces.

Yeah, I’m going to experiment with this, but I believe that Ember.js can be used to create sandboxed apps but that only covers sandboxing app runtime from the global scope. Ember.js doesn’t have an opinion about deployment related issues which need to be addressed to make embeddable apps.

Basically, Ember.js does not to make it more difficult to do that, but the bigger problem is deployment and cross domain communication.

Hiya, I’d like to exactly this, did you have any luck with your experiments? Cheers, Stephen

That’s how you do it. You can put multiple ones on the same page too.

Coolio! But how? Is there any docs on this approach? Thinking about how to target a sub apps I frame/sandbox. How do inject a sub app into the sandbox… I can fiddle but any help would be hugely appreciated… Stephen

So is that all i need to do, change the rootElement and skip oasis.js? Or should I combine the tootelement with oasis? /stephen

Yeah, all you need to do is use the root element. Oasis gives you some conveniences, but you don’t really need it to embed an ember app.

There’s a good article on embedding ember here, http://bendyworks.com/externally-embedding-ember/

If you’re using ember-cli you can tweak the build depending on what you’ve already got loaded on your page,

var EmberApp = require('ember-cli/lib/broccoli/ember-app');
  var app = new EmberApp({
      vendorFiles : {
          'jquery.js': false
      }
  });

https://stackoverflow.com/questions/25791495/how-do-i-exlcude-jquery-from-the-vendorfiles/25793942#25793942

Hi Chaps, I’m trying out Conductor just now and am a bit miffed by the complexity of the tutorial … All I want to do is embed 2 or more ember apps into a main app … Just to make sure I understood you right Ulises : I don’t need to use Conductor/Oasis to achieve this ? I should just be able to change the rootElement of each of the child apps? Look forward to your reply, Stephen.

Yup, simply changing the root element will do the job. You could use both of those libraries to achieve a more secure setup, but they’re not necessary. Unless that’s part of your business requirements, but you can probably leave that till later.

cool, so next question is how do I include my child app in the parent? I’m using ember-cli so I need to get the child app into the ES6 eco system … and try something like this :

import Ember from 'ember';
import m1 from 'm1-ui/app';

export default Ember.View.extend({
    classNames :['panel', 'panel-default'],
    didInsertElement : function(){

        var m1home = this.$('.child-app-m1');
        m1.reopen({
            rootElement : m1home
        });
        m1.create({});
    }
});

I’v included m1-ui in bower, so how do I get brocolli to include it in the build so I use an import? /Stephen.

hmm just tried this without ember-cli and got :

Error:
 Assertion Failed: You cannot make a new Ember.Application using a root 
element that is a descendent of an existing Ember.Application

child project :

M1 = Ember.Application.create({
    rootElement : '#m1ui'
});

M1.deferReadiness();

M1.Router.map(function() {
    this.resource('m1', {path:'/'}, function(){
        this.resource('m1_1', {path:'/m1_1'}, function(){});
        this.resource('m1_2', {path:'/m1_2'}, function(){});
        this.resource('m1_3', {path:'/m1_3'}, function(){});
    });
});

/* --- ROUTES --- */
M1.ApplicationRoute = Ember.Route.extend({
    renderTemplate: function() {
        this.render('m1Application', {
        });
    }
});

Parents ApplicationView

App.ApplicationView = Ember.View.extend({
    didInsertElement : function(){
        M1.advanceReadiness();
    }
})

Yeah you can’t put an ember app inside another ember app. You can have them living side-by-side though.

Is this the same for namespaced ember-cli apps? In that they can’t be emebedded?

@maitriyogin - Did you get any further ideas about how to nest applications within each other? Or, is there a way to use Components to yield a component from one app into another app?

Hiya, yeah I did! Please take a look at the code here :

git clone https://github.com/callistaenterprise/cadec-2015-ember.git
git checkout addons

Basically, it goes -app uses > -client uses > -domain … -app being the application and everything else as an addon. blogs-app uses the client addons ( blogs-client, login-client ) which in their turn use their respective domains ( users-client - users-domain, blogs-client - blogs-domain ). So the clients include client stuff, controllers, views, templates etc and the domains include domain stuff, ember data, services etc … hope it helps, Stephen.

1 Like