Working with Child Apps and Regions in FrintJS

Fahad Heylaal
FrintJS
Published in
4 min readDec 5, 2017
Illustration of a website design

In this article, we will focus on rendering FrintJS Child Apps in specific areas of our UI (which we call “Regions”), using React.js as our rendering library.

To make the most out of this article, it is advised that you read these two previous articles first:

What is a Region?

In a traditional website, you usually have elements like header, footer, sidebar, etc. They are areas in your website where you put relevant content accordingly.

  • Header: may contain logo and navigation links
  • Footer: more navigation, and copyright information
  • Main: your main content area
  • Sidebar: contextual information based on main area’s content

In FrintJS, we ship a <Region /> component via frint-react package (and also frint-vue), which allows us to define these areas in our applications.

You just define them, and later if there happens to be any Child App registered targeting any actively rendered Region, they will be rendered inside them. Otherwise it will render nothing in the UI.

How does it work?

Imagine this is our React component that is rendered from Root App (can be anywhere in the components tree):

import React from 'react';
import { Region } from 'frint-react';
export default function Root() {
return (
<div>
<div className="main">
...
</div>
<div className="sidebar">
<Region name="sidebar" />
</div>
</div>
);
}

All we did was just define a Region in our Component, and give it a unique name “sidebar”. It’s just a placeholder here for now, and it will render nothing in the UI until any Child App for this specific Region is available.

Register a Child App:

To see it action, we also need to register a Child App:

import RootApp from './root-app';
import ChildApp from './child-app';
window.app = new RootApp();window.app.registerApp(ChildApp, {
regions: ['sidebar'],
});

What we did above was, first have access to our Root Apps’s instance, and then register our Child App to it by specifying a list of region names where we want it to be rendered.

Now whenever the <Region name="sidebar" /> is rendered anywhere, it will take up the responsibility of rendering ChildApp too in it automatically.

Multiple Child Apps in a single Region:

You can register multiple Child Apps in your Region. If you want to take more control on the ordering of rendered Apps, you can make use of the weight key when registering. The lower the number, the higher they appear inside Region then:

window.app.registerApp(ChildApp1, {
regions: ['sidebar'],
weight: 5,
});
window.app.registerApp(ChildApp2, {
regions: ['sidebar'].
weight: 10,
});

Passing data via Regions:

Regions can also pass additional data as props, which can later be accessed as an RxJS Observable when needed by Child Apps.

Data can be passed as props like this:

import React from 'react';
import { Region } from 'frint-react';
function MyComponent() {
const data = {}; // anything
return (
<div>
<Region name="sidebar" data={data} />
</div>
);
}

This data via props (that can also change over time), can later be accessed via Child Apps using providers.

You can read more about it in the documentation here.

Code Splitting

You may wonder why we are using a global variable for the Root App’s instance in window.app.

Technique:

This is a technique we have been using at Travix, to help us split our big monolithic application into multiple bundles.

Webpack is really good at splitting your bundle into multiple chunks very efficiently, but that can only happen when all of your source code is accessible from a single entry point (think a single repository).

With this implementation of Regions via FrintJS, our primary application now only needs to be responsible for defining the Regions in the right places, without having to know early on what gets rendered in them. This enables our individual teams to work on their own Child Apps in their own repositories.

Responsibilities from server-side:

From our server, we can dynamically decide which Child Apps’ bundles to load on demand, and those bundles (once loaded) all register themselves by accessing the global window.app variable.

The server’s response looks pretty much like this:

<!-- common libraries, like React and FrintJS -->
<script src="./vendors.js"></script>
<!-- our Root App in FrintJS -->
<script src="./root.js"></script>
<!-- dynamically generated list of Child Apps -->
<script src="./child-1.js"></script>
<script src="./child-2.js"></script>
<script src="./child-3.js"></script>

Example

This topic on code splitting may require another dedicated blog post, but for now you can take a look at this example in our repository for a real-world use case: https://github.com/frintjs/frint/tree/master/examples/multiple-apps

Find us on Twitter if you have any questions!

--

--

Fahad Heylaal
FrintJS

Maker of things · JavaScript · RxJS · ReactJS