Customization is the tenant-level layer for changing how Jetstack looks, presents itself, and connects selected delivery channels without changing platform code. Use it when you want one implementation to feel branded, tenant-specific, or operationally isolated while still staying inside the standard platform model.
This area combines four different kinds of configuration:
- branding and theme settings for the tenant UI
- branding assets such as logos and icons
- delivery-channel settings for e-mail, SMS, and push-notification override routing
- tenant-owned editable assets such as custom CSS, templates, scripts, and environment variables
Customization lets you adapt a tenant in ways that are broader than a single module or view:
- You can make the UI match a client or business unit without rebuilding views.
- You can route outgoing communication through tenant-specific providers.
- You can isolate secrets and environment-specific values from the main application settings.
- You can extend presentation behavior with tenant files instead of editing the product codebase.
Use this area when the change is about tenant identity, tenant presentation, or tenant-owned integration values. If the change is about platform behavior defaults such as security, localization, or general application policy, use Application Settings instead.
This chapter is organized by the actual customization surfaces exposed by the platform:
- Branding and theme options
- Logo and icon assets
- Communication-channel settings
- Environment variables
- File-based customization editors
Each option is described in terms of what it controls, how to configure it, and what effect it has at runtime.
Customization works on top of the rest of the platform rather than replacing it:
- Builder configuration defines what the application can do.
- Application settings define tenant-wide behavior defaults.
- Customization defines tenant identity, presentation, and selected external-delivery details.
- File-based customization extends rendering and client-side behavior where the tenant is allowed to provide its own assets.
That separation matters because a visual or branding change should normally stay in Customization, while operational behavior such as access policy or object deletion policy belongs in Application Settings.
¶ Branding
The Branding group controls the tenant identity shown to users in the UI.
- Purpose: Defines the tenant-visible application title.
- How to configure it: Enter a short text value in the Web title field.
- Runtime effect: The value is used anywhere the tenant title is rendered by the application shell or related UI surfaces.
- When to use it: Set this when the tenant should present itself under a specific product, department, or client name.
- Guidance: Keep it short and stable. If the title is too long, it becomes harder to reuse in headers, browser titles, and compact navigation layouts.
- Purpose: Defines a short introductory or greeting message for the tenant.
- How to configure it: Enter plain text in the Welcome message field.
- Runtime effect: The text becomes part of the tenant-specific presentation layer where the platform renders the welcome message.
- When to use it: Use it for onboarding cues, environment labeling, or a short explanation of what the tenant is for.
- Guidance: Prefer concise wording. This is best used for orientation, not for long instructions.
The Theme group controls the design tokens used to generate the tenant theme. This is not a page-by-page styling tool. Instead, it defines a consistent visual system that the UI reuses across screens.
When you save theme changes, Jetstack validates the theme and recompiles the tenant bootstrap styling when needed. That means theme values are not just stored as metadata; they directly influence the generated UI CSS.
theme_preset chooses a predefined theme token set such as the default and additional built-in presets.
theme_preset_applied is an internal helper used by the UI to distinguish "selected preset not yet applied" from an already materialized token set. You do not configure this manually.
- If you choose a preset and apply it as a preset, the platform derives the theme from the preset definition.
- If you modify the individual token fields, the tenant effectively moves into a custom theme state even if it began from a preset.
Use presets when you want a fast, coherent baseline. Use individual token fields when you need a tuned tenant identity.
- Purpose: Selects a built-in visual starting point.
- How to configure it: Pick a value from the Preset selector.
- Runtime effect: The preset supplies a coordinated set of color, typography, spacing, rounding, and elevation tokens.
- When to use it: Use this first when creating a new tenant theme, especially if you want consistency without tuning every value manually.
- Guidance: Start from a preset that is already close to the intended brand and then refine only the necessary tokens.
- Purpose: Controls whether the tenant is rendered as light-only, dark-only, or both with a mode toggle.
- How to configure it: Select
light, dark, or both.
- Runtime effect: This changes which theme mode variants are available to the runtime UI.
- When to use it: Use
both when the tenant should support user choice. Use a single mode when branding or accessibility policy requires a fixed appearance.
- Guidance: Choose a single mode only if you are sure the tenant does not rely on user-selectable display preferences.
These fields define the primary semantic palette of the tenant.
- Purpose: Defines the main accent and action color.
- How to configure it: Enter or pick a color value in the color input.
- Runtime effect: Used for primary buttons, links in some contexts, and the main branded accent across the UI.
- When to use it: Match the tenant’s primary brand color.
- Guidance: Pick a color with enough contrast against both light and dark surfaces used by the theme.
- Purpose: Defines the secondary accent color.
- How to configure it: Enter a color value.
- Runtime effect: Used for secondary accents, supporting UI emphasis, and derived styling surfaces.
- When to use it: Use it when the tenant identity depends on a second branded color or when the default secondary tone does not fit the primary brand.
- Purpose: Defines the color used for success states.
- How to configure it: Enter a color value.
- Runtime effect: Affects success messages, positive states, and other semantic success surfaces.
- Guidance: Keep this visually distinct from the primary color so success feedback remains recognizable.
- Purpose: Defines the color used for informational states.
- How to configure it: Enter a color value.
- Runtime effect: Affects info alerts and other informational UI elements.
- Purpose: Defines the color used for warning states.
- How to configure it: Enter a color value.
- Runtime effect: Affects warning alerts and caution-oriented UI surfaces.
- Purpose: Defines the color used for destructive or error states.
- How to configure it: Enter a color value.
- Runtime effect: Affects destructive actions, errors, and danger-state components.
- Guidance: Keep this reserved for error semantics rather than general branding.
These values shape the general UI surface rather than just the semantic alert palette.
- Purpose: Defines the light neutral reference color.
- How to configure it: Enter a color value.
- Runtime effect: Used by light surfaces and supporting theme derivations.
- When to use it: Adjust this only when the tenant uses a warmer, cooler, or more branded neutral base than the default.
- Purpose: Defines the dark neutral reference color.
- How to configure it: Enter a color value.
- Runtime effect: Used by dark surfaces and supporting theme derivations.
- Guidance: If you support dark mode, this value strongly influences its visual character.
¶ theme_body_bg
- Purpose: Defines the default page and application background color.
- How to configure it: Enter a color value.
- Runtime effect: Changes the background surface behind the main UI.
- When to use it: Use a subtle brand tint only if it does not reduce readability or overload the UI.
¶ theme_body_text
- Purpose: Defines the default body text color.
- How to configure it: Enter a color value.
- Runtime effect: Changes the base text tone used across the application.
- Guidance: This should maintain strong readability against
theme_body_bg.
- Purpose: Defines the default link color.
- How to configure it: Enter a color value.
- Runtime effect: Applies to clickable text links and similar linked surfaces.
- Guidance: It is common to align this with the primary brand color, but it can differ if the tenant needs stronger distinction for links.
- Purpose: Defines the hover-state color for links.
- How to configure it: Enter a color value. This field is optional.
- Runtime effect: Changes link appearance on hover where that interaction state is rendered.
- When to use it: Set it when the default derived hover behavior is not visually clear enough.
- Purpose: Defines the base border color for cards, controls, tables, and related surfaces.
- How to configure it: Enter a color value.
- Runtime effect: Shapes how strongly UI boundaries are visually expressed.
- Guidance: Lower-contrast borders support a softer UI. Stronger borders help dense data-heavy implementations.
¶ Typography and rhythm
These fields control the reading density and general typographic feel of the tenant.
- Purpose: Defines the base font size used by the theme.
- How to configure it: Adjust the range input. The UI exposes a bounded slider rather than an arbitrary free-form size.
- Runtime effect: Changes text scale across the tenant.
- When to use it: Increase it for accessibility and readability, or reduce it carefully for highly dense internal tools.
- Guidance: Avoid reducing the size just to fit more content on screen. Prefer better layouts or filtering if density becomes a problem.
- Purpose: Defines the base line height preset for text.
- How to configure it: Choose one of the available presets such as compact, default, or relaxed.
- Runtime effect: Changes vertical text rhythm and readability.
- When to use it: Use compact for very dense operational interfaces, default for most business applications, and relaxed when readability matters more than compactness.
- Purpose: Defines the font weight used for headings.
- How to configure it: Select one of the available numeric weights.
- Runtime effect: Changes how strong headings feel relative to body text.
- Guidance: Stronger heading weights support dashboard-like interfaces. Slightly lighter headings can feel calmer in form-heavy systems.
- Purpose: Defines the base body font weight.
- How to configure it: Select a numeric weight or leave the field at its default behavior.
- Runtime effect: Changes the visual heaviness of regular text.
- When to use it: Change this only when the tenant branding or chosen font rendering makes the default body weight feel too thin or too heavy.
¶ Shape, spacing, and surface feel
These options change the personality of controls and containers without changing page structure.
- Purpose: Selects the global rounding preset.
- How to configure it: Choose one of the available presets such as
sharp, subtle, default, friendly, or round.
- Runtime effect: Changes corner radii across controls, cards, and related components.
- When to use it: Use sharper settings for formal enterprise interfaces and rounder settings for softer, more branded consumer-facing experiences.
- Purpose: Selects the spacing-density preset.
- How to configure it: Choose
compact, default, or spacious.
- Runtime effect: Changes how tightly content and controls are packed.
- When to use it: Use compact density for high-volume operational work. Use spacious density when form clarity and lower cognitive load are more important.
- Purpose: Defines how much shadow-based depth the UI uses.
- How to configure it: Choose
flat, subtle, default, or strong.
- Runtime effect: Changes the prominence of cards, controls, and layered surfaces.
- Guidance: Flat designs usually work well for administrative tools. Strong elevation should be used carefully because it can make dense screens feel noisy.
- Purpose: Defines the border thickness preset.
- How to configure it: Choose
thin, default, or thick.
- Runtime effect: Changes the strength of borders across the interface.
- When to use it: Thicker borders can help in highly structured interfaces or where shadow usage is minimal.
- Purpose: Defines the control sizing preset.
- How to configure it: Choose
compact, default, or large.
- Runtime effect: Changes padding and perceived scale of buttons, form controls, and similar interactive elements.
- When to use it: Use large controls for touch-oriented or accessibility-sensitive tenants. Use compact only when the implementation truly benefits from denser controls.
¶ Logos And Icons
The Logo and Icon group controls the tenant-owned visual assets used by the platform shell and e-mail rendering surfaces.
Each upload field supports two actions:
- upload a new image file
- erase the current custom value so the platform falls back to the default asset if one exists
Uploaded images must be image files and must not exceed 1024 by 1024 pixels. When you replace an asset, the tenant stores the new file in its customization area and removes the previous custom file.
- Purpose: Defines the web icon used by the tenant.
- How to configure it: Upload an image in the Web icon field.
- Runtime effect: Used where the tenant icon is rendered by the application shell or browser-facing surfaces.
- When to use it: Provide a simplified square icon rather than reusing a wide logo.
- Purpose: Defines the standard tenant logo.
- How to configure it: Upload an image in the Logo field.
- Runtime effect: Used on tenant UI surfaces that display the normal logo.
- Guidance: Use a transparent-background asset where possible so it works across more layout contexts.
- Purpose: Defines the logo variant intended for dark or inverted backgrounds.
- How to configure it: Upload an image in the inverted-logo field.
- Runtime effect: Used where the UI expects a logo suited to dark backgrounds.
- When to use it: Configure this whenever the normal logo loses contrast on dark navigation or header surfaces.
- Purpose: Defines the logo variant used in e-mail rendering.
- How to configure it: Upload an image in the e-mail logo field.
- Runtime effect: Used by mail-related rendering paths that display tenant branding in messages.
- Guidance: Use an e-mail-safe asset with comfortable margins and predictable rendering at smaller widths.
- Purpose: Remove the current tenant-owned asset for the related field.
- How to configure it: Tick the erase checkbox next to the corresponding upload and save.
- Runtime effect: The custom asset is deleted and the tenant falls back to the platform default asset if one is available.
- When to use it: Use this when a temporary branding asset should be retired without uploading a replacement.
The Mailing group controls whether tenant-originated e-mail is enabled, which sender identity is used by default, and which delivery backend should send the message.
This group does not define the message subject, recipients, content variables, or send trigger. Those belong to the automation, API, or template usage path that sends the e-mail. See Email Templates and Automations.
- Purpose: Enables or disables e-mail sending for the tenant.
- How to configure it: Set the Enable e-mails checkbox.
- Runtime effect: This acts as the tenant-level switch for whether e-mail sending is available.
- When to use it: Disable it in test tenants, placeholder tenants, or environments that must not send e-mail.
- Purpose: Defines the default human-readable sender name.
- How to configure it: Enter the sender display name.
- Runtime effect: Used as the default "from" name where no more specific sender name is supplied by the sending path.
- Guidance: Use a stable organizational label rather than a personal name unless the tenant truly models a personal mailbox.
- Purpose: Defines the default sender e-mail address.
- How to configure it: Enter a valid e-mail address.
- Runtime effect: Used as the default "from" address for tenant e-mail sending.
- Guidance: Make sure the selected delivery provider is allowed to send from this address or domain.
- Purpose: Selects the delivery connector used to send e-mail.
- How to configure it: Choose one of the available mailer providers from the Preferred mailer field.
- Runtime effect: The selected provider determines which additional configuration fields appear and how outgoing e-mail is delivered.
- When to use it: Choose the provider that matches the tenant’s infrastructure and sender-domain setup.
The exact additional fields depend on the selected mailer. Jetstack shows only the fields relevant to the chosen provider.
Use this when the tenant sends mail through an SMTP server.
- Purpose: Defines the SMTP server host name.
- How to configure it: Enter the host or relay address.
- Purpose: Defines the SMTP server port.
- How to configure it: Enter the port number as text.
- Purpose: Defines the SMTP transport security mode.
- How to configure it: Enter the encryption mode expected by the relay.
- Guidance: Match the provider requirement exactly, because an incorrect value can prevent delivery.
- Purpose: Defines the SMTP username.
- How to configure it: Enter the username required by the relay.
- Purpose: Defines the SMTP password or credential secret.
- How to configure it: Enter the relay password.
- Guidance: Treat this as a secret value and document ownership carefully.
- Purpose: Defines the client host value used by the SMTP connector.
- How to configure it: Enter the client host when the relay requires it.
- When to use it: Leave it aligned with the provider requirement. Use it only when your SMTP infrastructure expects a specific client host identity.
Use this when transactional e-mail should be sent through Ecomail.
- Purpose: Defines the Ecomail API key.
- How to configure it: Enter the API key in the provider-specific field shown after selecting the Ecomail connector.
- Runtime effect: The tenant uses the Ecomail API instead of SMTP.
Use this when the tenant sends e-mail through Resend.
- Purpose: Controls whether the tenant should reuse the platform default Resend key.
- How to configure it: Enable the Use default checkbox for the Resend connector.
- Runtime effect: When enabled, the runtime uses the default key provided by the platform configuration instead of a tenant-specific key.
- When to use it: Use this when multiple tenants intentionally share the same Resend account.
- Purpose: Defines the tenant-specific Resend API key.
- How to configure it: Enter the API key when the tenant should not reuse the platform default.
- Runtime effect: Used only when the tenant is not configured to use the default key.
Use this when the tenant sends e-mail through SMTP2GO.
- Purpose: Defines the SMTP2GO API key.
- How to configure it: Enter the provider key after choosing SMTP2GO as the preferred mailer.
- Runtime effect: The tenant uses the SMTP2GO API for delivery.
- Purpose: Enables recipient override for outgoing e-mail.
- How to configure it: Enable the checkbox and provide a target list in
mail_override_addresses.
- Runtime effect: Outgoing e-mail is redirected to the configured override recipients instead of the original recipients.
- When to use it: Use this in test, staging, migration, or certification phases when the tenant must generate mail but must not reach real recipients.
- Purpose: Defines the override recipient list for outgoing e-mail.
- How to configure it: Enter a JSON array of e-mail addresses such as
["qa@example.com","owner@example.com"].
- Runtime effect: The override list replaces the message recipients when e-mail override is enabled. The platform also appends a note containing the original recipient information so testers can still see who the message would have gone to.
- Guidance: This field must contain valid JSON and it must be a list of string values. Empty strings are ignored and duplicate values are normalized away.
The SMS group controls tenant-level SMS delivery settings and SMS recipient override behavior.
- Purpose: Enables or disables SMS sending.
- How to configure it: Set the Enable SMS checkbox.
- Runtime effect: Controls whether SMS delivery is available for the tenant.
- Purpose: Controls whether the tenant should reuse the default gateway settings.
- How to configure it: Enable the Use default gateway settings checkbox.
- Runtime effect: Signals that the tenant should rely on shared default SMS gateway configuration rather than maintaining a fully separate tenant-specific configuration.
- When to use it: Use this in centrally managed environments where a single SMS gateway serves multiple tenants.
- Purpose: Defines the BulkGate application ID.
- How to configure it: Enter the provider-issued application ID.
- Runtime effect: Used when the tenant relies on BulkGate credentials for SMS sending.
- Purpose: Defines the BulkGate application token.
- How to configure it: Enter the provider-issued token.
- Guidance: Treat this as a secret operational credential.
- Purpose: Defines the sender text shown for SMS messages where the gateway supports it.
- How to configure it: Enter the desired sender identifier.
- Runtime effect: Used as the message sender label in SMS delivery.
- Guidance: Make sure the chosen value is supported by the gateway and by the regulatory rules for the target countries.
- Purpose: Enables SMS recipient override.
- How to configure it: Enable the checkbox and provide
sms_override_numbers.
- Runtime effect: Outgoing SMS messages are redirected to the configured test numbers rather than the original recipients.
- When to use it: Use this in non-production tenants or during rollout validation.
- Purpose: Defines the SMS override targets.
- How to configure it: Enter a JSON array of phone numbers such as
["+420123456789","+420987654321"].
- Runtime effect: The platform uses these numbers when SMS override is enabled.
- Guidance: This field must contain a valid JSON list of string values.
The Push Notifications group currently focuses on override routing for Exponent tokens.
- Purpose: Enables push-token override behavior for the Exponent channel.
- How to configure it: Enable the checkbox and provide
exponent_override_tokens.
- Runtime effect: Push messages are rerouted to the configured test tokens instead of the original device tokens.
- When to use it: Use this when validating push-notification behavior without contacting real user devices.
- Purpose: Defines the test target tokens for push delivery override.
- How to configure it: Enter a JSON array of token strings.
- Runtime effect: The platform normalizes the list and uses it as the effective recipient token set when override is enabled.
- Guidance: Use actual Exponent tokens where possible. Keep the list small and controlled because this setting affects all overridden push deliveries for the tenant.
The Environment Variables tab stores tenant-owned named values outside the main application config surface. Use it when a tenant needs additional named inputs that should not become first-class global config keys.
This is especially useful for integration endpoints, tenant-specific identifiers, secrets, or presentation assets that are better treated as tenant variables than as builder data.
- They are named settings managed by the tenant rather than by the core configuration defaults.
- They can be typed, which means Jetstack can render them with richer input behavior instead of always treating them as plain text.
- They can be created and deleted from the customization UI.
- They are appropriate for operational values, not for domain data that should live in object types and records.
The Create or update variable dialog defines the variable metadata.
- Purpose: Defines the variable key.
- How to configure it: Enter a short identifier in the Code field.
- Runtime effect: This becomes the stored variable name.
- Important behavior: The value is sanitized to alphanumeric characters when saved. Characters outside
a-z, A-Z, and 0-9 are removed.
- Guidance: Choose a stable machine-friendly name from the start, because this is the identifier other configuration may depend on.
- Purpose: Defines the human-readable label of the variable.
- How to configure it: Enter a descriptive title.
- Runtime effect: The title is shown in the environment-variable table and related editing surfaces.
- Guidance: Use a title that explains the value’s purpose, not just its technical name.
- Purpose: Defines how the variable should be interpreted and rendered.
- How to configure it: Select a property type in the Type field.
- Runtime effect: If a type is defined, the platform renders the variable through the same property-field machinery used elsewhere in Jetstack. That means the edit control can become a file field, structured field, or another type-aware input instead of staying a plain text box.
- When to use it: Use a type when validation, richer editing, or non-text values matter.
- Purpose: Defines the initial stored value when the variable is created.
- How to configure it: Enter the initial value in the Initial value field.
- Runtime effect: The variable is created with this initial value.
- Guidance: Use a safe bootstrap value. For secrets, prefer entering the real value only in the appropriate secured environment.
- Purpose: Protects core configuration keys from being recreated as custom environment variables.
- Runtime effect: If the chosen code matches a reserved configuration key, the platform rejects the variable creation.
- Guidance: If a value belongs to core tenant configuration, keep it in its native setting instead of trying to mirror it as an environment variable.
Once a variable exists, it appears in the Environment Variables table.
- If the variable has no
type, it is edited as a plain text value.
- If the variable has a
type, Jetstack renders it using the type-aware property form machinery.
- If the value is file-based, saving commits the underlying file into the tenant variable context rather than storing only a text path.
- Purpose: Removes the variable from the tenant environment-variable store.
- How to configure it: Use the delete action on the variable row.
- Runtime effect: The variable disappears from the tenant configuration surface.
- Guidance: Before deleting a variable, make sure no templates, scripts, integrations, or custom logic still depend on it.
¶ Styles, Templates, And Scripts
The remaining customization tabs expose tenant-owned file editors. These tabs are different from the form-driven settings above because they work with files and folders rather than single config values.
Use them when the tenant needs a file-based extension or override rather than a simple setting.
The Styles tab opens a code editor rooted in the tenant customization CSS area.
- Purpose: Lets the tenant maintain custom CSS assets.
- How to configure it: Create or edit files in the Styles browser.
- Runtime effect: These files form the tenant-owned styling layer beyond the generated theme.
- When to use it: Use this when theme tokens are not enough and the tenant needs small targeted visual refinements.
- Guidance: Prefer theme options first. Use custom CSS only for cases that cannot be expressed through the theme token system.
The Templates tab opens a code editor rooted in the tenant template area.
- Purpose: Lets the tenant maintain custom template files.
- How to configure it: Edit files in the Templates browser.
- Runtime effect: Tenant template files can participate in the rendering layer where the platform supports custom templates.
- Feature availability: This tab is feature-gated. If the
customization_templates feature is not unlocked, the editor is replaced with a locked-feature message.
- Guidance: Use this carefully, because template customization creates a stronger coupling between the tenant and the rendering layer than branding or theme settings do.
The Scripts tab opens a code editor rooted in the tenant scripts area.
- Purpose: Lets the tenant maintain script files.
- How to configure it: Edit files in the Scripts browser.
- Runtime effect: These files provide a tenant-owned script layer where the platform supports custom script usage.
- Feature availability: This tab is feature-gated. If the
customization_scripts feature is not unlocked, the editor is replaced with a locked-feature message.
- Guidance: Keep these scripts focused and operationally documented, because file-based tenant behavior is harder to govern than form-based configuration.
Use the following decision model:
- Use Branding when the tenant needs a new title or welcome message.
- Use Theme when the tenant needs a cohesive visual identity change.
- Use Logo and Icon uploads when the tenant needs branded assets.
- Use Mailing, SMS, and Push settings when the tenant needs tenant-level communication routing.
- Use Environment Variables when the tenant needs named operational values that do not belong in the core configuration schema.
- Use Styles, Templates, or Scripts only when the requirement cannot be expressed with configuration alone.
Suppose you are preparing a client-branded tenant for pilot rollout:
- Set
appTitle to the client-facing name and add a short welcomeMessage.
- Choose a preset in
theme_preset, then adjust theme_color_primary, theme_body_bg, and theme_controls_size until the tenant matches the client brand.
- Upload
appLogo, appLogoInverted, and appLogoEmail.
- Enable
mail_override_enabled and configure mail_override_addresses so all pilot e-mails are redirected to the project team.
- Add environment variables for any client-specific API endpoint or tenant identifier.
- Only if needed, add small CSS refinements in the Styles tab instead of pushing visual changes into ad hoc view-level workarounds.
- Start with theme presets and token changes before adding custom CSS.
- Keep tenant branding assets versioned and named consistently outside the platform as part of rollout governance.
- Use override recipient settings aggressively in non-production or pilot environments.
- Treat provider keys, tokens, and gateway secrets as operational assets with clear ownership.
- Use environment variables for integration values, not for business records or user-editable domain data.
- Document every file-based customization because it is less discoverable than form-based configuration.
- Remove temporary override routing before production go-live.