Modules

What It Is

A module is Jetstack's navigation entry and experience container for a domain area. It tells the platform:

  • how the module appears in navigation
  • what kind of link the module represents
  • what content should open when the module is entered
  • who may see it
  • whether it can be exposed publicly or embedded

Why It Matters

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:

  • a normal in-app destination
  • a wrapper around a default view
  • a custom layout or canvas-based landing page
  • an external link
  • a structural heading in navigation

How To Read This Chapter

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:

  • identity and labels
  • link and destination behavior
  • content and rendering behavior
  • navigation hierarchy
  • access and exposure

Use this chapter together with:

Mental Model

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.

Configuration Options

Identity And Labeling

OptionWhat it controlsHow to configure itNotes
module_nameMain 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_titleDisplay 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.
iconIcon 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.

Identity Details

module_name

Use this as the stable module label in the implementation.

Good examples:

  • Customers
  • Finance
  • Legal
  • Operations

This field is required on create and edit.

module_title

This is the display-oriented title shown when the module is rendered. The runtime explicitly fills it from module_name when empty, so:

  • use it when the displayed module title should differ from the administrative name
  • leave it empty when the same wording is correct in both places

This is especially useful when:

  • the navigation label should be shorter
  • the page heading should be more descriptive
  • translated or localized naming needs a cleaner display label
OptionWhat it controlsHow to configure itNotes
link_typeWhat 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_hrefExplicit 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_viewView 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.

Jetstack defines four link types:

  • Module
  • Within app
  • External
  • None

Module

This is the normal module behavior.

Use it when:

  • the module should open its own module page
  • the module is a real Jetstack destination
  • you want the module to use default_view, layout, or canvas

Runtime behavior:

  • the generated link points to Module:default for normal modules
  • or Module:public when is_public is enabled and the public link is used

This is the usual choice for business-area modules.

Within app

Use this when the module should navigate to another internal application route directly.

Configure:

  • link_type = Within app
  • link_href with a valid internal application destination

Runtime behavior:

  • the module link is produced through $app->link($this->link_href)
  • the module acts more like a navigation shortcut than a self-contained module page

Use this when:

  • the best destination is another presenter or route
  • the module should behave like an alias or shortcut into an existing screen

External

Use this when the module should open an external URL.

Configure:

  • link_type = External
  • link_href with the full external target URL

Runtime behavior:

  • the module link is the raw configured external URL

Use this sparingly and intentionally. External modules make sense when Jetstack is one part of a wider tool landscape.

None

Use this when the module should not be a direct destination.

Runtime behavior:

  • the generated module link is empty
  • in navigation templates, modules with this link type behave like structural entries or headings
  • this is the main pattern for parent/grouping nodes with children

Use it when:

  • the module exists to organize child modules
  • the navigation needs headings rather than more destinations

How to configure it depends on the selected link type:

  • for Within app, enter the internal target expected by the application's link system
  • for External, enter the full external URL
  • for Module or None, this is usually left empty

Treat this field as a contract:

  • internal links should stay valid when modules evolve
  • external links should point to stable destinations

default_view

This field is more important than it first appears.

Runtime rendering order:

  1. if neither layout nor canvas is set, the module renders default_view in a full-screen module page
  2. if either layout or canvas is set, the module renders through the module template file instead

So 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:

  • the module should simply open a view
  • you do not need a custom layout page
  • a canvas would be unnecessary complexity

Content And Rendering

OptionWhat it controlsHow to configure itNotes
layout_fileLayout 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.
layoutModule-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.
canvasCanvas 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.

Rendering Precedence

The module runtime works like this:

  1. if neither layout nor canvas is set: the module falls back to default_view
  2. if layout or canvas is set: the module renders a generated module template file
  3. if canvas is set: the generated template renders the canvas control
  4. otherwise: the generated template renders the layout content

In plain terms:

  • canvas wins over layout
  • layout wins over default_view
  • default_view is the simple fallback

layout_file

This controls the broader wrapper around the module page.

Use it when:

  • the module should use a specific page shell
  • a custom wrapper is needed for styling, structure, or public-page presentation

Do not confuse it with:

  • layout, which is the module body content
  • canvas, which is a canvas-based module body

layout

Use this when:

  • the module needs a custom composed page
  • you want module-specific HTML or layout content
  • a simple full-screen default view is not enough

Important runtime note:

  • the module content is written into a tenant file under TENANT_DIR/modules/<moduleId>.latte
  • if a canvas is present, the module template becomes a canvas control call instead

This means layout is appropriate for carefully designed module entry pages, dashboards, or landing layouts.

canvas

Use this when:

  • the module should open a canvas-driven experience
  • the module needs a highly tailored landing page
  • a more visual or assembled page model is required

The presenter also loads canvas meta tags for module pages, which makes canvas-backed modules especially useful for richer experiences.

Read Canvases.

OptionWhat it controlsHow to configure itNotes
parent_moduleParent 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_module

Use this when:

  • you want child modules under a broader section
  • the navigation should be grouped by business area
  • the parent module acts as a structural heading

This is especially powerful with link_type = None on the parent module.

Typical pattern:

  • parent module People with link_type = None
  • child modules Employees, Recruiting, Policies

That gives you a clean navigation section instead of a long flat list.

Access And Exposure

OptionWhat it controlsHow to configure itNotes
available_to_rolesRoles 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_publicWhether 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_hostsWhich 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_activeWhether 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_roles

This field defines which roles the module is available to.

Use it when:

  • a domain area should be visible only to specific roles
  • navigation itself should respect role boundaries
  • the module is not appropriate as a globally visible entry point

This is a module-level navigation/access concept and should be designed together with Roles And Permissions.

is_public

When this is enabled:

  • the module can expose a public link
  • the module presenter can render it through Module:public
  • the module becomes part of the public surface of the tenant

Use it for:

  • public portals
  • externally reachable landing modules
  • controlled public entry points

Do not enable it casually. A public module should be reviewed as a public-facing asset, not just a convenient shortcut.

allowed_framing_hosts

This field controls who may frame the public module.

Runtime behavior:

  • when the module is opened publicly, the presenter reads allowed_framing_hosts
  • if the first configured host is *, framing is allowed from anywhere
  • otherwise, the HTTP referer host must appear in the allowed-host list

Use this when:

  • a public module should be embedded in a known external portal
  • you need to restrict which hosts may frame the module

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_active

Use this to control whether the module should be part of the active navigation experience.

Disable it when:

  • the module is being prepared but should not yet be visible
  • the module has been retired but not fully removed
  • the navigation structure is being migrated in stages

Common Module Patterns

Standard Destination Module

Use:

  • link_type = Module
  • default_view set
  • no custom layout or canvas unless needed

This is the simplest and most maintainable pattern.

Dashboard Or Landing Module

Use:

  • link_type = Module
  • a custom layout or canvas
  • optional default_view only as fallback when no custom content is present

This is a good fit for rich module entry pages.

Structural Navigation Module

Use:

  • link_type = None
  • child modules through parent_module

This is the best pattern for section headings and grouped navigation.

External Shortcut Module

Use:

  • link_type = External
  • link_href set to the external target

This works when Jetstack is part of a broader business-tool landscape.

Internal Shortcut Module

Use:

  • link_type = Within app
  • link_href set to the internal route

This is good when a module should serve as a shortcut to another application area instead of a self-contained module page.

Public Embedded Module

Use:

  • is_public = true
  • allowed_framing_hosts configured deliberately
  • a purpose-built layout or canvas

This is the right pattern for public portals and embedded external experiences.

Design Questions To Ask Before Finalizing A Module

  • Is this module a real destination or just a structural navigation node?
  • Should it open a default view, a custom layout page, or a canvas?
  • Should it be visible to everyone, only some roles, or publicly?
  • Does it need to be embeddable in another host?
  • Would a parent-child module structure make the navigation clearer?
  • Is link_type = Within app or External actually the right abstraction, or should this be a normal module instead?

Best Practices

  • Design modules around user journeys and business areas, not around raw table structure.
  • Use link_type = None intentionally for structural parent modules.
  • Prefer default_view for straightforward list-entry modules.
  • Use layout or canvas only when the module truly needs a custom landing experience.
  • Treat is_public and allowed_framing_hosts as exposure and security decisions, not convenience toggles.
  • Keep module_name stable and use module_title when the user-facing title needs different wording.