How to Add a New Component
This guide explains how to add a new microfrontend component (ending with _component
) to this repository, using our existing template structure.
1. Create Your New Component Inside This Repo
1.1. Copy the Template Component
Naming
The name of your new microfrontend must end with
_component
.Example:
Correct:
yourAmazingMicrofrontend_component
Incorrect:
yourAmazingMicrofrontend
Reason: The TypeScript declarations in
core/src/declaration.d.ts
recognize names ending in*_component
. Using any other naming convention will cause type errors.
Duplicate the Template
Copy the entire
template_component
folder.Rename it to your new component’s name, ensuring you include the
_component
suffix.
Update
webpack.config.ts
In your new component’s
webpack.config.ts
, update the following constants:COMPONENT_NAME
(set this to your component’s name)COMPONENT_DEV_PORT
(assign a unique port for local development, e.g.3001
. Make sure it does not collide with other components in this repo.)
Adjust the Naming in Other Files
<yourName_component>/Dockerfile
: Rename all instances oftemplate_component
to your new component name.<yourName_component>/package.json
: Update the"name"
field to match your component.
Register Your Component in the Monorepo
lerna.json
>packages
package.json
>packages
eslint.config.mjs
>workspaceFolders
Make sure your new component folder is listed so it’s recognized by the build and lint processes.
Install Dependencies
Run
yarn install
at the repository root to ensure your new component is properly integrated.
Implement Your Functionality
Add pages, components, and other logic as needed for your new microfrontend.
Export Your Functionality via Routes and Sidebar
Configure your sidebar in
sidebar/index.tsx
You can define a single sidebar item that contains multiple subitems.
Top-level sidebar items can display an icon (subitems do not).
Both items and subitems can have different permission restrictions.
Important: The top-level sidebar item should have the lowest required permissions. Subitems are only visible if their parent item is accessible.
Configure your routes in
routes/index.tsx
Ensure the routes match the sidebar structure and permission settings.
Each sidebar path must correspond to a route with the same access restrictions.
You may add extra routes that are not listed in the sidebar, but do not create sidebar entries without corresponding routes.
2. Integrate Your Component with the Core
2.1. Update core/webpack.config.ts
Determine the URL of your new component (e.g., via an environment variable).
In the
ModuleFederationPlugin > remotes
section, add an entry for your new component so it can be dynamically loaded.
2.3. Map the Component to Course Phases
We assume that every component is associated to one course phase type. The course phase types are stored in the DB. We assume here that you already have a course phase type to which you want to map your component.
Sidebar Mapping
In
core/src/managementConsole/PhaseMapping/PhaseSidebarMapping.tsx
, map the course phase type name to your new<YourName>Sidebar
.
Router Mapping
In
core/src/managementConsole/PhaseMapping/PhaseRouterMapping.tsx
, map the same course phase type name to your new<YourName>Routes
.
3. Deploy Your Component
Environment Variables
If your component references an environment variable (e.g.,
COMPONENT_SUBPATH
), add it in GitHub’s settings and add it incore/public/env.template.js
so that it is available at runtime.
GitHub Workflows
build-and-push-clients.yml
: Add another output image tag and the building script for for your component. Use the template component as example.deploy-docker
: Include the new image tag (and path env variable) in the “SSH to VM and create .env.prod file” step to ensure Docker Compose picks it up.dev.yml
: Reference the new image tag.prod.yml
: Reference the new image tag.
Docker Compose
In
docker-compose.prod.yml
, follow the existing template for deployment. Rename or adjust the middlewares/services as needed to match your new component.
2. Create a New Component Outside This Repo
Not yet supported.
Note:
For an external component, the
shared_library
must be published in full, and you must adjust thepublicPath
accordingly inwebpack.config.ts
.
Happy coding! If you run into issues or have questions, please reach out @niclasheun or refer to existing components for reference.