A module is Jetstack's navigation entry and experience container for a domain area. It tells the platform:
Modules shape the first impression of a solution. A strong module structure makes the tenant feel coherent and intentional. A weak one makes even a good data model feel scattered.
Modules are also more than menu items. Depending on configuration, a module can behave as:
Unlike some other builder objects, the module resource does not define custom form groups of its own. The most useful way to document it is by capability area:
Use this chapter together with:
Keep these distinctions clear:
module_name is the main internal and administrative label.module_title is the display-facing title. If left empty, the runtime falls back to module_name.link_type defines where the navigation entry goes.default_view, layout, and canvas define what the module renders when it opens.parent_module defines navigation nesting, not data ownership.available_to_roles, is_public, and allowed_framing_hosts define who can reach the module and from where.| Option | What it controls | How to configure it | Notes |
|---|---|---|---|
module_name |
Main name of the module. | Enter a stable, recognizable name such as Sales, HR, Projects, or Knowledge Base. |
This is the title-role field and the main administrative identifier used in the builder. |
module_title |
Display title of the module. | Enter the title users should see in the heading and navigation. | If left empty, the runtime fills it from module_name. |
icon |
Icon shown for the module in navigation and entry points. | Choose an icon that matches the module's business meaning. | This is a semantic navigation signal. Reuse icon conventions across related modules. |
module_nameUse this as the stable module label in the implementation.
Good examples:
CustomersFinanceLegalOperationsThis field is required on create and edit.
module_titleThis is the display-oriented title shown when the module is rendered. The runtime explicitly fills it from module_name when empty, so:
This is especially useful when:
| Option | What it controls | How to configure it | Notes |
|---|---|---|---|
link_type |
What kind of navigation target the module represents. | Choose one of Module, Within app, External, or None. |
This is one of the most important module settings. |
link_href |
Explicit target used by non-module link types. | Enter the internal presenter/action target or the external URL, depending on link_type. |
Most relevant for Within app and External. |
default_view |
View opened when the module has no layout and no canvas. | Select the fallback view the module should show. | This is the standard "full screen view" fallback when neither layout nor canvas is configured. |
link_type In DetailJetstack defines four link types:
ModuleWithin appExternalNoneModuleThis is the normal module behavior.
Use it when:
default_view, layout, or canvasRuntime behavior:
Module:default for normal modulesModule:public when is_public is enabled and the public link is usedThis is the usual choice for business-area modules.
Within appUse this when the module should navigate to another internal application route directly.
Configure:
link_type = Within applink_href with a valid internal application destinationRuntime behavior:
$app->link($this->link_href)Use this when:
ExternalUse this when the module should open an external URL.
Configure:
link_type = Externallink_href with the full external target URLRuntime behavior:
Use this sparingly and intentionally. External modules make sense when Jetstack is one part of a wider tool landscape.
NoneUse this when the module should not be a direct destination.
Runtime behavior:
Use it when:
link_hrefHow to configure it depends on the selected link type:
Within app, enter the internal target expected by the application's link systemExternal, enter the full external URLModule or None, this is usually left emptyTreat this field as a contract:
default_viewThis field is more important than it first appears.
Runtime rendering order:
layout nor canvas is set, the module renders default_view in a full-screen module pagelayout or canvas is set, the module renders through the module template file insteadSo default_view is not the universal main content field. It is specifically the fallback content model for standard modules without custom page composition.
Use default_view when:
| Option | What it controls | How to configure it | Notes |
|---|---|---|---|
layout_file |
Layout wrapper file used when rendering the module page. | Select the layout file to use. The default points to the standard @layout.latte file. |
Required on create and edit. This is the page shell, not the module body content itself. |
layout |
Module-specific layout content rendered inside the module page when no canvas takes over. | Enter the HTML or Latte-safe content the module should render. | If a canvas is set, the canvas takes precedence and layout acts as fallback. |
canvas |
Canvas used to render the module body. | Select a canvas when the module should open a custom canvas-based page. | This is the strongest content override for module rendering. |
The module runtime works like this:
layout nor canvas is set:default_viewlayout or canvas is set:canvas is set:layout contentIn plain terms:
canvas wins over layoutlayout wins over default_viewdefault_view is the simple fallbacklayout_fileThis controls the broader wrapper around the module page.
Use it when:
Do not confuse it with:
layout, which is the module body contentcanvas, which is a canvas-based module bodylayoutUse this when:
Important runtime note:
TENANT_DIR/modules/<moduleId>.latteThis means layout is appropriate for carefully designed module entry pages, dashboards, or landing layouts.
canvasUse this when:
The presenter also loads canvas meta tags for module pages, which makes canvas-backed modules especially useful for richer experiences.
Read Canvases.
| Option | What it controls | How to configure it | Notes |
|---|---|---|---|
parent_module |
Parent module in the navigation tree. | Select the parent module when this module should appear nested under another one. | This is a navigation relationship, not a data or permission hierarchy. |
parent_moduleUse this when:
This is especially powerful with link_type = None on the parent module.
Typical pattern:
People with link_type = NoneEmployees, Recruiting, PoliciesThat gives you a clean navigation section instead of a long flat list.
| Option | What it controls | How to configure it | Notes |
|---|---|---|---|
available_to_roles |
Roles that may access or see the module. | Select the roles that should have access to the module. | This is a multi-role relation and part of the module's access surface. |
is_public |
Whether the module may be opened through its public route. | Enable only when the module should be reachable publicly. | Public exposure meaningfully changes the risk profile of the module. |
allowed_framing_hosts |
Which referring hosts may embed the public module. | Configure this as an array of allowed host names, or * to allow any host. |
This matters only for public module embedding scenarios. |
is_active |
Whether the module is active in the current navigation model. | Enable for modules that should participate in the active tenant experience. | Use inactive modules only for staged or retired navigation assets. |
available_to_rolesThis field defines which roles the module is available to.
Use it when:
This is a module-level navigation/access concept and should be designed together with Roles And Permissions.
is_publicWhen this is enabled:
Module:publicUse it for:
Do not enable it casually. A public module should be reviewed as a public-facing asset, not just a convenient shortcut.
allowed_framing_hostsThis field controls who may frame the public module.
Runtime behavior:
allowed_framing_hosts*, framing is allowed from anywhereUse this when:
Configure it as an array of host names such as:
["portal.example.com", "partners.example.com"]
Use ["*"] only when fully open framing is truly intended.
is_activeUse this to control whether the module should be part of the active navigation experience.
Disable it when:
Use:
link_type = Moduledefault_view setThis is the simplest and most maintainable pattern.
Use:
link_type = Modulelayout or canvasdefault_view only as fallback when no custom content is presentThis is a good fit for rich module entry pages.
Use:
link_type = Noneparent_moduleThis is the best pattern for section headings and grouped navigation.
Use:
link_type = Externallink_href set to the external targetThis works when Jetstack is part of a broader business-tool landscape.
Use:
link_type = Within applink_href set to the internal routeThis is good when a module should serve as a shortcut to another application area instead of a self-contained module page.
Use:
is_public = trueallowed_framing_hosts configured deliberatelylayout or canvasThis is the right pattern for public portals and embedded external experiences.
link_type = Within app or External actually the right abstraction, or should this be a normal module instead?link_type = None intentionally for structural parent modules.default_view for straightforward list-entry modules.layout or canvas only when the module truly needs a custom landing experience.is_public and allowed_framing_hosts as exposure and security decisions, not convenience toggles.module_name stable and use module_title when the user-facing title needs different wording.