SCION Microfrontend Platform | Projects Overview | Changelog | Contributing | Sponsoring |
---|
SCION Microfrontend Platform > Getting Started > Browse Catalog of Capabilities
In this chapter, we will browse the catalog of capabilities to dynamically construct the top-level navigation.
Prepare the microfrontends for contributing to the navigation bar
In chapter 6, we already provided the ProductList Microfrontend as microfrontend capability. We now need to do the same for the CustomerList Microfrontend.
-
Open the manifest
customers-app/src/manifest.json
of the Customers App. -
Register the CustomerList Microfrontend as
microfrontend
capability, as follows:{ "name": "Customers App", "capabilities": [ [+] { [+] "type": "microfrontend", [+] "qualifier": { [+] "entity": "customers" [+] }, [+] "private": false, [+] "properties": { [+] "path": "/customer-list/customer-list.html", [+] "navbar": { [+] "label": "Customers" [+] } [+] } [+] }, { "type": "microfrontend", "qualifier": { "entity": "customer" }, "params": [ { "name": "id", "required": true } ], "properties": { "path": "/customer/customer.html#?id=:id", "outlet": "aside" } } ], "intentions": [ { "type": "microfrontend", "qualifier": { "entity": "products" } } ] }
Note that we set the custom property
navbar
in the properties section of the capability. We will read this property when filtering the catalog of capabilities to determine for which microfrontends to create a navbar item. -
Open the manifest
products-app/src/manifest.json
of the Products App and add the propertynavbar
to theProductList Microfrontend
, as follows:{ "name": "Products App", "capabilities": [ { "type": "microfrontend", "qualifier": { "entity": "products" }, "params": [ { "name": "ids", "required": false } ], "private": false, "properties": { "path": "/product-list/product-list.html#?ids=:ids", [+] "navbar": { [+] "label": "Products" [+] } } }, { "type": "microfrontend", "qualifier": { "entity": "product" }, "params": [ { "name": "id", "required": true } ], "properties": { "path": "/product/product.html#?id=:id", "outlet": "aside" } } ] }
Declare intention to browse microfrontend capabilities
In order for the host app to browse and navigate to microfrontend capabilities, we need to declare an intention, as follows:
- Open the file
host-app/src/host.ts
. - Declare a microfrontend wildcard intention, as follows:
await MicrofrontendPlatformHost.start({ applications: [ {symbolicName: 'products-app', manifestUrl: 'http://localhost:4201/manifest.json'}, {symbolicName: 'customers-app', manifestUrl: 'http://localhost:4202/manifest.json'}, { symbolicName: 'devtools', manifestUrl: 'https://microfrontend-platform-devtools.scion.vercel.app/manifest.json', intentionCheckDisabled: true, scopeCheckDisabled: true, }, ], host: { manifest: { name: 'Host App', intentions: [ {type: 'microfrontend', qualifier: {component: 'devtools', vendor: 'scion'}}, [+] {type: 'microfrontend', qualifier: {'*': '*'}}, ], }, }, });
Remove static navigation buttons
-
Open the file
host-app/src/index.html
of the host app. -
Remove the buttons in the
<nav>
element, as follows:Before:
<nav> <button id="products">Products</button> <button id="customers">Customers</button> </nav>
After:
<nav></nav>
-
Open the file
host-app/src/host.ts
of the host app. -
Remove the event listeners of the static buttons we removed in the previous step.
Populate the navigation bar
- Open the file
host-app/src/host.ts
of the host app. - Create a button for each of the microfrontend capabilities to be added to the navigation bar, as follows:
[+] import {ManifestService, MicrofrontendPlatformHost, OutletRouter} from '@scion/microfrontend-platform';
import {Beans} from '@scion/toolkit/bean-manager';
[+] import {filterArray} from '@scion/toolkit/operators';
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'},
{
symbolicName: 'devtools',
manifestUrl: 'https://microfrontend-platform-devtools.scion.vercel.app/manifest.json',
intentionCheckDisabled: true,
scopeCheckDisabled: true,
},
],
host: {
manifest: {
name: 'Host App',
intentions: [
{type: 'microfrontend', qualifier: {component: 'devtools', vendor: 'scion'}},
{type: 'microfrontend', qualifier: {'*': '*'}},
],
},
},
});
// Display the DevTools
Beans.get(OutletRouter).navigate({component: 'devtools', vendor: 'scion'}, {outlet: 'bottom'});
[+] // Create a navigation button for each of the microfrontend capabilities to be added to the navigation bar
[+] const navbar = document.querySelector('nav');
[+] Beans.get(ManifestService).lookupCapabilities$({type: 'microfrontend'})
[+] .pipe(filterArray(capability => capability.properties.navbar))
[+] .subscribe(capabilities => {
[+] navbar.innerHTML = null;
[+] capabilities.forEach(capability => {
[+] const menuItem = navbar.appendChild(document.createElement('button'));
[+] menuItem.innerText = capability.properties.navbar.label;
[+] menuItem.addEventListener('click', () => {
[+] Beans.get(OutletRouter).navigate(capability.qualifier);
[+] });
[+] })
[+] });
Using the ManifestServie
, we can browse the catalog of capabilities and pass a filter to return only the capabilities that are of interest to us. We further filter capabilities having the navbar
property. For each of these capabilities, we create a button that, when clicked, navigates to the microfrontend of that qualifier.
Open the app in the browser
We did it! Run npm run start
to serve the applications and see that the navigation buttons are now contributed via capabilities.
What we did in this chapter
In this chapter, we learned how to browse the catalog of capabilities to dynamically populate the navigation bar.
The customers-app/src/manifest.json
looks as following:
{
"name": "Customers App",
"capabilities": [
{
"type": "microfrontend",
"qualifier": {
"entity": "customers"
},
"private": false,
"properties": {
"path": "/customer-list/customer-list.html",
"navbar": {
"label": "Customers"
}
}
},
{
"type": "microfrontend",
"qualifier": {
"entity": "customer"
},
"params": [
{
"name": "id",
"required": true
}
],
"properties": {
"path": "/customer/customer.html#?id=:id",
"outlet": "aside"
}
}
],
"intentions": [
{
"type": "microfrontend",
"qualifier": {
"entity": "products"
}
}
]
}
The products-app/src/manifest.json
looks as following:
{
"name": "Products App",
"capabilities": [
{
"type": "microfrontend",
"qualifier": {
"entity": "products"
},
"params": [
{
"name": "ids",
"required": false
}
],
"private": false,
"properties": {
"path": "/product-list/product-list.html#?ids=:ids",
"navbar": {
"label": "Products"
}
}
},
{
"type": "microfrontend",
"qualifier": {
"entity": "product"
},
"params": [
{
"name": "id",
"required": true
}
],
"private": true,
"properties": {
"path": "/product/product.html#?id=:id",
"outlet": "aside"
}
}
]
}
The host-app/src/index.html
looks as following:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Getting Started with SCION</title>
<link rel="stylesheet" type="text/css" href="host.scss">
<script type="module" src="./host.ts"></script>
</head>
<body>
<nav></nav>
<main>
<sci-router-outlet></sci-router-outlet>
<sci-router-outlet name="aside"></sci-router-outlet>
<sci-router-outlet name="bottom"></sci-router-outlet>
</main>
</body>
</html>
The host-app/src/host.ts
looks as following:
import {ManifestService, MicrofrontendPlatformHost, OutletRouter} from '@scion/microfrontend-platform';
import {Beans} from '@scion/toolkit/bean-manager';
import {filterArray} from '@scion/toolkit/operators';
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'},
{
symbolicName: 'devtools',
manifestUrl: 'https://microfrontend-platform-devtools.scion.vercel.app/manifest.json',
intentionCheckDisabled: true,
scopeCheckDisabled: true,
},
],
host: {
manifest: {
name: 'Host App',
intentions: [
{type: 'microfrontend', qualifier: {component: 'devtools', vendor: 'scion'}},
{type: 'microfrontend', qualifier: {'*': '*'}},
],
},
},
});
// Display the DevTools
Beans.get(OutletRouter).navigate({component: 'devtools', vendor: 'scion'}, {outlet: 'bottom'});
// Create a navigation button for each of the microfrontend capabilities to be added to the navigation bar
const navbar = document.querySelector('nav');
Beans.get(ManifestService).lookupCapabilities$({type: 'microfrontend'})
.pipe(filterArray(capability => capability.properties.navbar))
.subscribe(capabilities => {
navbar.innerHTML = null;
capabilities.forEach(capability => {
const menuItem = navbar.appendChild(document.createElement('button'));
menuItem.innerText = capability.properties.navbar.label;
menuItem.addEventListener('click', () => {
Beans.get(OutletRouter).navigate(capability.qualifier);
});
})
});
}
}
new HostController().init();
What's next
You have now learned the core concepts of the SCION Microfrontend Platform. Click here for a summary and further reading.