SCION Microfrontend Platform | Projects Overview | Changelog | Contributing | Sponsoring |
---|
SCION Microfrontend Platform > Getting Started > Microfrontend Navigation
In the past two chapters we created the Products App and Customers App and integrated their microfrontends in the primary router outlet of the host app. In this chapter we are going to change the navigation to the Product Microfrontend and Customer Microfrontend so that they are displayed in the named outlet to the right of the primary outlet.
So far, we have not had to register our micro apps in the host app because they did not interact with the platform. In order to register a micro app, the app must provide a manifest file, which is a special file that contains information about the application, such as its intentions and capabilities. We will learn more about capabilities and intentions in the next chapter.
Provide a manifest file for the micro apps
-
Create an empty file in the directory
products-app/src
and name itmanifest.json
. Then add the application's name to the manifest, as follows:{ "name": "Products App" }
-
Create an empty file in the directory
customers-app/src
and name itmanifest.json
. Then add the application's name to the manifest, as follows:{ "name": "Customers App" }
Register the micro apps in the host
Micro apps which want to interact with the platform need to be registered in the host. To register the Products App and Customers App, open the file host-app/src/host.ts
and register them, as follows:
public async init(): Promise<void> {
await MicrofrontendPlatformHost.start({
applications: [
[+] {symbolicName: 'products-app', manifestUrl: 'http://localhost:4201/manifest.json'},
[+] {symbolicName: 'customers-app', manifestUrl: 'http://localhost:4202/manifest.json'},
],
});
// Install navigation listeners
document.querySelector('button#products').addEventListener('click', () => {
Beans.get(OutletRouter).navigate('http://localhost:4201/product-list/product-list.html');
});
document.querySelector('button#customers').addEventListener('click', () => {
Beans.get(OutletRouter).navigate('http://localhost:4202/customer-list/customer-list.html');
});
}
Each micro app must be assigned a unique symbolic name. The micro app will use that symbolic name to connect to the platform. The registration further requires the URL to the application's manifest which we created in the previous step.
Install the SCION Microfrontend Platform
- Run the following command to install the SCION Microfrontend Platform in the Products App.
cd products-app npm install @scion/microfrontend-platform @scion/toolkit rxjs@^7.5.0 --save
- Run the following command to install the SCION Microfrontend Platform in the Customers App.
cd customers-app npm install @scion/microfrontend-platform @scion/toolkit rxjs@^7.5.0 --save
Open the *Product Microfrontend* to the right of the *ProductList Microfrontend*
-
In the Products App, open the file
products-app/src/product-list/product-list.ts
. -
Change the
init
method to connect to the platform host and passproducts-app
as the application's symbolic name. It must be exactly the same symbolic name under which we registered the app in the host.import {ProductService} from '../product.service'; import {QueryParams} from '../query-params'; [+] import {MicrofrontendPlatformClient} from '@scion/microfrontend-platform'; public async init(): Promise<void> { [+] await MicrofrontendPlatformClient.connect('products-app'); QueryParams.observe$.subscribe(queryParams => { const productIds = queryParams.get('ids')?.split(','); this.render(productIds); }); }
-
Change the
render
method to open the Product Microfrontend to the right of the products, as follows:import {ProductService} from '../product.service'; import {QueryParams} from '../query-params'; [+] import {MicrofrontendPlatformClient, OutletRouter} from '@scion/microfrontend-platform'; [+] import {Beans} from '@scion/toolkit/bean-manager'; public render(ids?: string[]): void { const productsSection = document.querySelector('section#products'); productsSection.innerHTML = null; ProductService.INSTANCE.getProducts({ids}).forEach(product => { // Product Name const productLink = productsSection.appendChild(document.createElement('a')); productLink.innerText = product.name; [+] productLink.addEventListener('click', () => { [+] Beans.get(OutletRouter).navigate(`/product/product.html#?id=${product.id}`, {outlet: 'aside'}); [+] }); // Product Price productsSection.appendChild(document.createTextNode(`$ ${product.price.toFixed(2)}`)); }); }
Instead of specifying the
href
attribute, add a click listener to the link. When clicked, use the router to navigate the passed URL in the specified outlet.
Open the *Customer Microfrontend* to the right of the *CustomerList Microfrontend*
-
In the Customers App, open the file
customers-app/src/customer-list/customer-list.ts
. -
Change the
init
method to connect to the platform host and passcustomers-app
as the application's symbolic name. It must be exactly the same symbolic name under which we registered the app in the host.import {CustomerService} from '../customer.service'; [+] import {MicrofrontendPlatformClient} from '@scion/microfrontend-platform'; public async init(): Promise<void> { [+] await MicrofrontendPlatformClient.connect('customers-app'); this.render(); }
-
Change the
render
method to open the Customer Microfrontend to the right of the customers, as follows:import {CustomerService} from '../customer.service'; [+] import {MicrofrontendPlatformClient, OutletRouter} from '@scion/microfrontend-platform'; [+] import {Beans} from '@scion/toolkit/bean-manager'; public render(): void { const customersSection = document.querySelector('section#customers'); CustomerService.INSTANCE.getCustomers().forEach(customer => { // Customer Link const customerLink = customersSection.appendChild(document.createElement('a')); customerLink.innerText = `${customer.firstname} ${customer.lastname}`; [+] customerLink.addEventListener('click', () => { [+] Beans.get(OutletRouter).navigate(`/customer/customer.html#?id=${customer.id}`, {outlet: 'aside'}); [+] }); // City customersSection.appendChild(document.createTextNode(customer.city)); }); }
Instead of specifying the
href
attribute, add a click listener to the link. When clicked, use the router to navigate the passed URL in the specified outlet.
Open the app in the browser
We did it! Run npm run start
to serve the applications.
When you open the page http://localhost:4200 in your browser and open a product or customer, that microfrontend should now be opened to the right of the product or customer list.
What we did in this chapter
In this chapter, we changed the navigation to the Product Microfrontend and Customer Microfrontend so that they are displayed in a named router outlet to the right of the primary outlet.
The products-app/src/manifest.json
looks as following:
{
"name": "Products App",
}
The customers-app/src/manifest.json
looks as following:
{
"name": "Customers App"
}
The host-app/src/host.ts
looks as following:
import {MicrofrontendPlatformHost, OutletRouter} from '@scion/microfrontend-platform';
import {Beans} from '@scion/toolkit/bean-manager';
class HostController {
public async init(): Promise<void> {
await MicrofrontendPlatformHost.start({
applications: [
{symbolicName: 'products-app', manifestUrl: 'http://localhost:4201/manifest.json'},
{symbolicName: 'customers-app', manifestUrl: 'http://localhost:4202/manifest.json'},
],
});
// Install navigation listeners
document.querySelector('button#products').addEventListener('click', () => {
Beans.get(OutletRouter).navigate('http://localhost:4201/product-list/product-list.html');
});
document.querySelector('button#customers').addEventListener('click', () => {
Beans.get(OutletRouter).navigate('http://localhost:4202/customer-list/customer-list.html');
});
}
}
new HostController().init();
The products-app/src/product-list/product-list.ts
looks as following:
import {ProductService} from '../product.service';
import {QueryParams} from '../query-params';
import {MicrofrontendPlatformClient, OutletRouter} from '@scion/microfrontend-platform';
import {Beans} from '@scion/toolkit/bean-manager';
class ProductListController {
public async init(): Promise<void> {
await MicrofrontendPlatformClient.connect('products-app');
QueryParams.observe$.subscribe(queryParams => {
const productIds = queryParams.get('ids')?.split(',');
this.render(productIds);
});
}
public render(ids?: string[]): void {
const productsSection = document.querySelector('section#products');
productsSection.innerHTML = null;
ProductService.INSTANCE.getProducts({ids}).forEach(product => {
// Product Name
const productLink = productsSection.appendChild(document.createElement('a'));
productLink.innerText = product.name;
productLink.addEventListener('click', () => {
Beans.get(OutletRouter).navigate(`/product/product.html#?id=${product.id}`, {outlet: 'aside'});
});
// Product Price
productsSection.appendChild(document.createTextNode(`$ ${product.price.toFixed(2)}`));
});
}
}
new ProductListController().init();
The customers-app/src/customer-list/customer-list.ts
looks as following:
import {CustomerService} from '../customer.service';
import {MicrofrontendPlatformClient, OutletRouter} from '@scion/microfrontend-platform';
import {Beans} from '@scion/toolkit/bean-manager';
class CustomerListController {
public async init(): Promise<void> {
await MicrofrontendPlatformClient.connect('customers-app');
this.render();
}
public render(): void {
const customersSection = document.querySelector('section#customers');
CustomerService.INSTANCE.getCustomers().forEach(customer => {
// Customer Link
const customerLink = customersSection.appendChild(document.createElement('a'));
customerLink.innerText = `${customer.firstname} ${customer.lastname}`;
customerLink.addEventListener('click', () => {
Beans.get(OutletRouter).navigate(`/customer/customer.html#?id=${customer.id}`, {outlet: 'aside'});
});
// City
customersSection.appendChild(document.createTextNode(customer.city));
});
}
}
new CustomerListController().init();
What's next
In the next chapter, we will learn how to embed a microfrontend in a microfrontend. Click here to continue.