Introducing support for cross-domain Glimmer components, with zoid

Daniel Brain
4 min readApr 6, 2017

This article is part of a series on PayPal’s Cross-Domain Javascript Suite.

I was pretty excited to see Glimmer released recently. As a big fan of Ember, even though I haven’t had much of a chance to use it professionally over the last few years, I think Glimmer is a great direction for the framework to take.

So, of course, I had to try writing some bindings for zoid.

If you haven’t tried it, zoid is a cross-domain-component library I maintain, and I’ve already written about how to integrate it with React. Glimmer seemed like the next logical step! With zoid, we can write Glimmer components and share them with other sites using iframes.

Create and implement your zoid component

I’ve gone over this in a lot of detail elsewhere, but I want to quickly throw together a zoid component. We’re going to use the standard example of a login component:

var MyLoginXComponent = zoid.create({    tag: 'my-login-component',
url: 'http://www.my-site.com/my-login-component'
});

That tells zoid where to render the component — and now I need to implement the component under that url.

I’m free to do so with whatever technology I want, then use window.xprops to get any of the data/callbacks that were passed down into the iframe from the parent window. I’m guessing since you’re reading this that you’ll be using Glimmer to implement that page — but that’s up to you. One of the advantages of zoid is, the parent page and child component window don’t need to be using any of the same technologies.

There’s a quick example of an implementation for MyLoginZoidComponent using vanilla javascript and window.xprops here. It’s taking window.props.prefilledEmail and calling window.xprops.onLogin(email) when the user logs in.

Pull in zoid and the login component to your Glimmer app

For now we’re just going to edit src/ui/index.htm to include zoid and the MyLoginZoidComponent definition we just defined, into our Glimmer app:

<script src="https://cdn.rawgit.com/krakenjs/zoid/master/dist/zoid.js"></script>
<script src="https://cdn.rawgit.com/krakenjs/zoid/master/demo/frameworks/glimmer/login.js"></script>

Set up the component in your Glimmer app

Now for the fun bit — the Glimmer binding! This lets you render a zoid component directly into a Glimmer handlebars template, using the Glimmer’s native syntax.

First, you’ll need to create a new Glimmer component. We do that by creating a directory under src/ui/components which we’re going to call log-in which will end up being our tag name, and we’re going to create a component.ts and a template.hbs. You can even do this step automatically by typing ember g glimmer-component log-in.

Since our component is going to be rendered into an iframe using zoid, we can just set the template.hbs to an empty <div></div>.

Then, all that’s left to do is to pull in the zoid Glimmer driver in component.ts:

import Component from '@glimmer/component';export default MyLoginZoidComponent.driver('glimmer', Component);

There’s a full example of how this should look here.

Render the component

Now we’ve set up the zoid binding and created a Glimmer component to wrap our zoid component, we can go ahead and render the component!

First let’s set up our parent app, and create some data and callbacks to pass down to the component:

import Component, { tracked } from "@glimmer/component";export default class MyApp extends Component {    @tracked loggedIn = false;
@tracked email = '';
@tracked prefilledEmail = 'foo@bar.com'; onLogin(email) {
this.loggedIn = true;
this.email = email;
}
}

We’re going to pass down a prefilledEmail and listen for an onLogin callback.

Now, we can just drop the component into our app’s template:

<div>
<h1>Log in on xyz.com</h1>
{{#unless loggedIn}}
<log-in @prefilledEmail={{prefilledEmail}}
@onLogin={{action onLogin}}></log-in>
{{else}}
<p>User logged in with {{email}}</p>
{{/unless}}
</div>

And we’re done! You can see the full code for this here. We have a Glimmer app, and a zoid component rendered into an iframe:

The example repo for this is here: https://github.com/bluepnume/glimmer-xcomponent-example.

Enjoy!

A few thoughts on Glimmer…

I was really impressed with what I saw so far, in the few hours I spent playing around with Glimmer. I just had a few quick thoughts —

  • Ideally I was hoping there would be a way to register a Glimmer component to the App’s registry without having to set up a new component directory with a template, for the three lines of code needed to bind Glimmer to our zoid component. Anyone know how? The folder structure is great if I’m building an app, no so great if I’m adding in a library and I want to programmatically create components.
  • I’m sad that there isn’t a development copy of glimmer.js that I could run without setting up the entire ember-cli ecosystem and buying into typescript, etc. I get that Glimmer templates are precompiled to fast bytecode for production, but when I was developing I would really have liked to just pull in a glimmer.js file and starting playing with glimmer.Component, with a run-time template compiler.
  • There seems to be a lot missing from the Glimmer docs that I had to go back to the Ember docs to find — and since various parts of the api had changed from Ember, I was a little lost trying to figure out what the delta was in features and interfaces. Things like actions, computed properties, etc.
  • I think the Ember/Glimmer philosophy of “support big apps from the ground up” is a great goal, but the problem for me is, a lot of these big apps are already written in some other framework or technology. I wish Glimmer had more love for people who want to incrementally transition over to it.

Anyway, generally speaking, really love what I’ve seen so far! Awesome work @GlimmerJS team! Can’t wait to see how people use it with zoid too.

--

--