Building with Modules

What are they?

Per our docs, modules allow you to build a

reusable group of components and queries. You might use a module to reuse common components in multiple apps or split up common functionality into smaller parts. For example, you can use modules to:

  • Create common search filters
  • Build a navigation bar to use across all your apps
  • Share forms between apps
  • Break large, complex apps into smaller, more maintainable parts

We highly encourage you to read through the full documentation, but we’re also including some tips & tricks here :wrench:

Things to keep in mind:

  • Modules are created in a separate editor from the app editor, but they can be drag and dropped into any app.
  • Any component can be used inside of a module.
  • Modules can have their own queries, but they can also receive data from the parent app or send data to the parent app
  • You will create the module once, and then can add it to any app as many times as needed. Any changes you make to the module will update all instances of the module.

When should I use modules?

The most common use case for modules is a navigation bar. The benefit of using a module for this use case, is that you only have to build it once, and then you can drag & drop it into any app. We’ll go through an example below.

There are some cases that may not be right for a module. For example, if you know your app will always have a table, three select components, and an image, you might consider using a module so that you only have to drag & drop those components once for each app. However, if those components will have different datasets and different component settings for each dataset, it may not be helpful to put them into a module. Generally, modules should be used for cases where there is consistency in the component configuration.

Some teams will use modules as a workaround to multi-player, meaning that one team member can edit the module, while another edits the parent app. Using the separate editors ensures that their work isn’t overwritten while they ultimately work on two parts of the same project. That said, we’re working on a multi-player feature! We should have some exciting updates soon :slight_smile:

Do modules help with performance?

No, generally, using modules in your app will not speed up your app. Modules are not lazy loaded into the app currently. See this post for more info: Best practices to improve editor performance (or to not ruin performance)

Can you nest modules (put modules inside of other modules)?

Yes, you can do this, but we suggest being mindful of when you do this because it can be very tricky to troubleshoot bugs.

Example Case:

  1. Create a new module. You’ll notice that the module editor looks very similar to the app editor, except that it comes with a single container--there’s no header, sidebar, or drawers. All of your components will go into the container. Keep in mind this container spans the width of the canvas, but you may want to adjust it for the actual size that you want it to take up in your app

  2. We’ll start by adding a navigation component and configuring the nav to link to two different apps.

  3. Once we import the module into our parent apps, we are going to want to have the current app highlighted, so we’ll need to add a module input. The input will be a dynamic value that is passed in from the parent app. In our case, the value will be the name of the parent app. To create an input, click on the canvas outside of the module container to view the settings in the right side inspector, or click the module container & then select “module settings." Add an input with Type data and give it a default value to use for testing purposes:

The default value will be any dummy value that you want to test out while you’re editing the module. To reference the module input dynamically inside the module, use inputName.value

  1. Set your nav component's links to be highlighted when the input value is equal to the name of that tab

  1. Next, go to each app that you want to use and drag & drop your module. I’m going to add my module to the header of my app 1 and app 2:

image

  1. Then, define each module input in the app with that app’s name. Repeat for all apps.

:tada: Now, I could easily add a third app to my menu or pass some data from the module - such as the logo information- to my apps as an output.

The example above uses a data input (the data being the name of the parent app), but inputs can also be a query type.

Query inputs allow you to trigger parent app queries from your module. For example, I can create a button in my module that will trigger confetti in my parent app:

  1. I'll create a query input, and trigger it on button click inside my navigation module.
  2. Then, I'll go to each of my apps that uses the module & assign input2 to a Javascript query in the parent app that triggers confetti:

:tada: Now, I can trigger confetti in my apps by clicking the button in my navigation header module

Other tips:

  • If you’re building a module for particular app, we recommend periodically testing the module in your app as you’re building. Sometimes you have to tweak the size of the module container in the module editor in order for it to have the right spacing in your parent app.

  • Custom css & preloaded Javascript aren’t supported in modules. Once you drag & drop the module into the app, any css or preloaded js you configured in the module editor will stop working.

  • Do not name your module the same as your inputs or outputs. For example, if your module is called navigationBar, do not make your module input navigationBar.value

  • When you export an app to JSON, the module will also be exported

4 Likes