Part 3: Building a simple application using the Entando ACP
Tags: beginners, tutorial, modular, application
Published: 2022-03-09 03:14:06

{% youtube UeqLYLvwf4Q %}

In the previous blogs, we learned about the[ 4c’s](https://www.entando.com/page/en/part_1_what_is_entando?contentId=BLG5707&modelId=64) and we also installed Entando on our local machines. In this blog, we are going to implement the 4c’s to create a very simple bundle and deploy it to our Entando Platform.

## The question is, what is a Bundle?

_An Entando Component Repository or ECR bundle is a package containing one or more components and a 'descriptor.yaml' file providing information about the bundle. The bundle is published on a Git registry and is shared with an Entando application using the EntandoDeBundle custom resource._

At first, we will create a widget that we would deploy to our Entando Platform. So currently, we are working as a creator. To do so, we’ll open up our favorite code editor/terminal, create a new folder and name it: `product-listing`.  

A little idea about what we’re going to build. We’ll build a simple React application that displays a few cards with some data on them, and this is what we define as our micro frontend (MFE). Then, we’ll run and build the React MFE. We next bundle up the entire MFE using ENT CLI and deploy it to the Entando Component Repository. Finally, we’ll install it in our App Builder, and drag and drop the cards widget (the one we created in React) to our Page!

Well, it might sound like a huge project, but it’s easy. 

To begin, we will refer to this [GitHub](https://github.com/entando-samples/ent-project-template) repository. This repository is an Entando project template that helps us to create a micro frontend, microservice, or both. Since we’ll focus on the micro frontend today, we’ll delete unnecessary files and folders from this project template, after we clone it. We’ll also rename the folders with respect to our project. And then copy everything inside the product-listing folder that we created previously. It should typically look like the structure below:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kxylhf3203piqpwfy9tu.png)

Inside the `widgets-dir` folder, the `cards-widget` folder is the React app that we create, as I’ve deleted the existing widget `et-app` from the `widgets-dir`  folder. We can name it as per our own preference. I’ve created mine:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l85wqpvc9p95439so9c8.png)

For the `bundle_src` folder (inside `product-listing` directory), we can see a `descriptor.yaml` file. In there, we need to paste the following yaml code:


```
code: product-listing
description: Template for simple cards design
components:
 widgets:
   - ui/widgets/widgets-dir/cards-widget/cards-descriptor.yaml
```

This is a yaml file, through which we are telling the Entando Bundler that our widget is present inside the `cards-widget` folder. And we are pointing it to the `cards-descriptor.yaml` file that is present inside another bundle folder (one that we create inside our React app i.e inside `cards-widget` directory). If we have more widgets inside the `widgets-dir` folder, then we need to add them here too.

Now, I’m assuming you have followed the above folder structure and created a bundle folder with a `cards.ftl` file and a `cards-descriptor.yaml` file inside the `cards-widget` folder. Hence, we go to the `cards-widget > bundle > cards.ftl` file and add the following content:

```
<#assign wp=JspTaglibs["/aps-core"]>
<#-- entando_resource_injection_point -->
<#-- Don't add anything above this line. The build scripts will automatically link the compiled JS and CSS for you and add them above this line so that the widget can be loaded-->

<@wp.info key="currentLang" var="currentLangVar" />
<cards-widget locale="${currentLangVar}"/>
```

That’s it for this .ftl file. What typically happens here is, when we build our project using the ENT CLI command, all the build scripts and link tags appear here.

Under the same bundle directory, inside the `cards-descriptor.yaml` file, we add the following code: 

```
code: cards-section
titles:
 en: Sample Cards Section Template
 it: Sample Cards Section Template
group: free
customUiPath: cards.ftl
```

So far, we have filled all our descriptor files, ftl file, and have created our React app. 

We keep the  `prepareBundle.sh` and `prepareMicrofrontend.sh` files untouched, as they act like the engine of our machine!

Now that we are all done configuring all the files, we jump inside the `cards-widget` folder and start designing our React app to display a set of cards. Inside the `src` folder, we create a new file and name it `cards.js`. We open up a terminal inside this directory and add a package to use bootstrap:

```
npm install react-bootstrap bootstrap@5.1.3
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/okqo72xl0mxa3w5kg0o7.png)

Now we add the following code to our `cards.js` file:

```
import "bootstrap/dist/css/bootstrap.min.css";
import { Card, CardGroup } from "react-bootstrap";

export default function App() {
 return (
   <div>
     <CardGroup>
       <Card>
         <Card.Body style={{ backgroundColor: "#F4ECF7" }}>
           <Card.Title>Much Scalable</Card.Title>
           <Card.Text>
             Our product xyz is very scalable and has grown a lot in the past 2
             years. More extra text here to explain.
           </Card.Text>
         </Card.Body>
         <Card.Footer style={{ backgroundColor: "#D6EAF8" }}>
           <small className="text-muted">Last updated 8 mins ago</small>
         </Card.Footer>
       </Card>
       <Card>
         <Card.Body style={{ backgroundColor: "#F4ECF7" }}>
           <Card.Title>Very Fast</Card.Title>
           <Card.Text>
             Our product xyz is very fast and has proven itself a lot in the
             past 2 years. More extra text here to explain.{" "}
           </Card.Text>
         </Card.Body>
         <Card.Footer style={{ backgroundColor: "#D4EFDF" }}>
           <small className="text-muted">Last updated 3 mins ago</small>
         </Card.Footer>
       </Card>
       <Card>
         <Card.Body style={{ backgroundColor: "#F4ECF7" }}>
           <Card.Title>Free to use</Card.Title>
           <Card.Text>
             Our product xyz is absolutely free to use and is available to
             download directly from our website. More extra text here to
             explain.
           </Card.Text>
         </Card.Body>
         <Card.Footer style={{ backgroundColor: "#FCF3CF" }}>
           <small className="text-muted">Last updated 4 days ago</small>
         </Card.Footer>
       </Card>
     </CardGroup>
   </div>
 );
}
```

And in our `app.js` file, we replace the existing content with the following:

```
import "./App.css";
import Cards from "./cards";

function App() {
 return (
   <div className="App">
     <Cards />
   </div>
 );
}

export default App;
```

Now that we have created our application, we need to wrap the entire React app into a custom element. Hence, we add a new file `src/WidgetElement.js` with the following custom element:

```
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

class WidgetElement extends HTMLElement {
 connectedCallback() {
   this.mountPoint = document.createElement("div");
   this.appendChild(this.mountPoint);
   ReactDOM.render(<App />, this.mountPoint);
 }
}

customElements.define("cards-widget", WidgetElement);

export default WidgetElement;
```

Then, open `src/index.js` and replace the entire file with these two lines:

```
import './index.css';
import './WidgetElement';
```

Lastly, we go to `public/index.html` and` `replace <code>&lt;div id="root">&lt;/<strong>div</strong>></code> with the custom element <code>&lt;cards-widget /></code>, like this:

```
<body>
     <noscript>You need to enable JavaScript to run this app.</noscript>
     <cards-widget />
</body>
```

Perfect! Now, we need to build our React app before we build the entire bundle.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b35rud6t5syz1aowrhhu.png)

To do so, we run:

```
npm run build
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/66eqk8smxlki56es21lv.png)

We go to the root directory of the project. In our case, it is `product-listing`, and set up the Project Directory: 

To follow the steps below, we need to have our terminal open on the root directory. Then, we can run the following commands in the terminal.

* Prepare the bundle directory `cp -r bundle_src bundle` 

Here, the descriptor.yaml file gets copied to the bundle folder, where all our static resources will be created when we build the bundle going forward. So, in a way, we are preparing the bundle folder. 

* Initialize the project: `ent prj init`
* Initialize publication: `ent prj pbs-init`  

In this phase, we need an empty GitHub repository that we link here for our bundled code to be pushed to. This repository should be named like: `product-listing-bundle`

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c74wap9emdegakujbdu2.png)

* Attach to Kubernetes for an Entando application via ent attach-kubeconfig config-file or similar.

Now, we publish the bundle to Entando App Builder:

* Build: `ent prj fe-build -a` (to just build the frontend, including changes from `bundle_src`) 

This is where our bundle is built, and remember i mentioned about the `cards.ftl` file? That all the script and link tags are injected there? Well, this is the step where it happens. So right after you execute this step, you can go to the `cards.ftl` file inside your bundle folder of the React app, and you’ll see those tags.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nw91xyofbjw1z5thech6.png)

* Publish: `ent prj fe-push` (publish just the frontend)
* Deploy (after connecting to k8s above): `ent prj deploy`

At this point, we are pushing everything to the Entando Component Repository.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tup115dxxflhm477grem.png)

That’s all. Congratulations you just built a micro frontend using React, bundled it and deployed it.

Normally, here starts the Curation Phase. We are not using a Hub here. But, in general, when we have a Hub (The Hub is a central catalog where many curators and teams can share and collaborate on components or bundles. They can publish and manage versions, share metadata and communicate about features.), we publish and deploy a bundle to it. A curator validates it and ensures that components, business capabilities, and solutions are ready for composition, defining prerequisites and updating capabilities with the latest patches or upgrades. In our case, we imagine the Entando Component Repository to be the Hub and we are the curators for now. 

Now it’s time we Compose the application from the Entando Component Repository.

At first, we login to our Entando App Builder:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0ka5ugn10o8nqpi1k5yy.png)

We first see our dashboard, and from the dashboard, we navigate to the left button of our page, where we see “repository”. Click on it.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1mzjmpimyo80q65b31nn.png)

We can see our product-listing bundle here, and so we install it. 

Then, we go to Pages from the left sidebar. And click on Management.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k5kimvzbb0mq9fbmqn8v.png)

Here we add a page to our page tree, and design its layout to have some page frames, so that our widget(s) can fit. And then we save and design!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4oq81w0jjfl50aubpf4z.png)

Here we see a list of widgets on the right sidebar, under “users”. We drag and drop the “Sample Cards Section Template” to any part of our page frame and click on publish. Then click on “view published page” and boom!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m2d87ctvmmiivihsbsc8.png)

Congratulations again! You did it!

So, If people come to use this application, they would be Consumers of our application. But since this was just a demo to understand the workflow, we didn’t actually consume the application!

Well, that was just a little bit, so you understand the process. Like this, a team of many people can contribute to this same application. They can have widgets built in Angular, Vue, or Next.js and have them all here on a single web page. Isn’t that fascinating?

To check out if you’ve missed anything, do take a look at my uploaded source [code](https://github.com/rimmi21/product-listing) at GitHub.

With this, we come to the end of our blog series, Getting started with Entando. You can see more [blog](https://www.entando.com/page/en/blog) posts on our website. We’re also building a community, where we can rapidly create a culture of Modular Applications along with you all. If that sounds interesting, do join us on our [discord](https://discord.gg/YSwEdaCc) community! Thank you!