ServiceNow Jelly: Complete Guide

Share

ServiceNow Jelly

ServiceNow Jelly is an XML-based templating and scripting technology used to generate dynamic user interfaces in the ServiceNow platform. It is particularly important when working with UI Pages, UI Macros, UI Formatters, and other classic platform interfaces that need server-side rendering. Although newer ServiceNow development increasingly uses modern UI technologies, Jelly remains relevant in existing implementations and in specific platform components.

A consultant working on a mature ServiceNow instance will often encounter Jelly code while maintaining custom UI Pages, reviewing existing UI Macros, troubleshooting classic forms, or upgrading applications. Understanding Jelly therefore remains valuable even when the implementation strategy is to minimize new Jelly development.

ServiceNow documentation describes UI Macros as scripted components that can be added to the user interface, and specifically notes that creating custom UI Macros requires knowledge of Jelly scripting.

This article explains Jelly from an implementation perspective, including its architecture, namespaces, common tags, UI Pages, UI Macros, practical examples, troubleshooting techniques, and development best practices.

What Is ServiceNow Jelly?

Jelly is a Java- and XML-based scripting and processing technology originally associated with Apache Jelly. ServiceNow uses Jelly to transform XML-style markup and embedded logic into HTML and other rendered UI content.

In practical terms, a Jelly page combines:

  • XML-style markup
  • ServiceNow Jelly tags
  • Server-side JavaScript
  • Dynamic variables
  • Conditional logic
  • Iteration
  • ServiceNow APIs
  • HTML
  • UI Macro references

A simplified Jelly structure looks like this:

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false"
    xmlns:j="jelly:core"
    xmlns:g="glide"
    xmlns:j2="null"
    xmlns:g2="null">

    <div>
        Hello ${gs.getUserDisplayName()}
    </div>

</j:jelly>

The important point is that Jelly is not simply HTML. The Jelly processor evaluates the dynamic portions of the page and produces the final output.

ServiceNow’s scripting documentation identifies j namespaces as standard Jelly functionality and g namespaces as ServiceNow-specific functionality.

Where Is Jelly Used in ServiceNow?

Jelly is most commonly encountered in the classic ServiceNow user interface and in records designed specifically for server-rendered UI components.

Important areas include:

ComponentTypical Jelly Usage
UI PagesComplete custom pages and dialogs
UI MacrosReusable UI controls
UI FormattersAdding custom elements to forms
Dictionary attributesReferencing certain UI Macros
Classic UI componentsServer-rendered interface elements
Custom dialogsDynamic dialog content
Legacy customizationsExisting implementations requiring maintenance

A UI Macro, for example, is stored as a record containing a name and XML/Jelly code. ServiceNow documentation states that administrators can create custom UI Macros and that they can be called from UI Pages and other supported UI components.

Jelly Architecture and Processing Model

One of the most important concepts for troubleshooting Jelly is understanding that the code is processed on the server before the resulting interface reaches the browser.

A simplified flow is:

User requests UI Page
        |
        v
ServiceNow processes Jelly
        |
        +---- Evaluate server-side logic
        |
        +---- Resolve Jelly variables
        |
        +---- Execute Glide APIs where applicable
        |
        +---- Generate HTML
        |
        v
Rendered HTML sent to browser
        |
        v
Browser displays interface

This distinction is critical.

For example, the following code executes server-side:

<g:evaluate var="jvar_message">
    var message = "Request created successfully";
    message;
</g:evaluate>

<div>
    ${jvar_message}
</div>

The browser does not execute the GlideRecord or g:evaluate operation itself. The server processes the Jelly code and sends the resulting HTML.

This is one reason Jelly should not be confused with client-side JavaScript.

Understanding Jelly Namespaces

Jelly namespaces are fundamental to ServiceNow development.

Common namespaces include:

j Namespace

The j namespace represents core Jelly functionality.

Example:

<j:if test="${condition}">
    <div>Condition is true</div>
</j:if>

Typical uses include:

  • Conditions
  • Loops
  • Variable operations
  • Standard Jelly processing

g Namespace

The g namespace contains ServiceNow-specific Jelly functionality.

For example:

<g:evaluate var="jvar_result">
    var result = "ServiceNow";
    result;
</g:evaluate>

The g namespace is especially important when interacting with ServiceNow server-side functionality.

j2 and g2

ServiceNow also supports second-phase processing through j2 and g2.

This is an area where developers frequently make mistakes.

Jelly processing can involve different phases, and ServiceNow documentation and scripting references distinguish the standard and second-phase namespaces.

When modifying an existing Jelly implementation, do not automatically replace g2 with g or j2 with j. The processing phase may be intentional.

Common Jelly Tags

The following tags are frequently encountered while maintaining ServiceNow Jelly code.

TagPurpose
<j:jelly>Root Jelly element
<j:if>Conditional processing
<j:forEach>Iteration
<g:evaluate>Execute server-side JavaScript
<g:ui_form>Generate form-related UI
<g:ui_input_field>Generate input fields
<g:ui_checkbox>Generate checkbox controls
<g:macro_invoke>Invoke a UI Macro
<g:requires>Include required UI resources

ServiceNow documentation provides examples of ServiceNow-specific tags such as g:evaluate, UI field tags, and UI Macro invocation.

Real-World Jelly Use Cases

Use Case 1 – Custom Approval Information Page

A company has a customized approval process where managers need a dedicated classic UI page showing:

  • Request number
  • Requested for
  • Requested item
  • Approval status
  • Comments
  • Approval history

Instead of building several independent components, a UI Page can use Jelly to retrieve the relevant record and dynamically generate the HTML.

The page can:

  1. Receive a record identifier.
  2. Retrieve the record.
  3. Validate access.
  4. Display relevant fields.
  5. Generate approval actions.
  6. Return the rendered page.

The important implementation consideration is authorization. A UI Page should never expose information simply because a user can manipulate a URL parameter.

Use Case 2 – Reusable UI Macro

Suppose an organization repeatedly displays an application status indicator.

Rather than duplicating the HTML in multiple UI Pages, a developer can create a UI Macro.

For example:

<j:jelly trim="true"
    xmlns:j="jelly:core"
    xmlns:g="glide">

    <div class="status-container">
        <strong>${jvar_status}</strong>
    </div>

</j:jelly>

The page can then pass the required value into the macro.

ServiceNow documents that attributes supplied to a UI Macro are exposed to the macro using jvar_-prefixed variables.

For example:

<g:ui_example
    name="Request"
    test_attribute="Approved"
    laptop_type="Standard" />

The UI Macro can access these values through variables such as:

jvar_name
jvar_test_attribute
jvar_laptop_type

Use Case 3 – Legacy Form Customization

Many enterprise ServiceNow environments contain customizations created years ago.

During an upgrade, developers may discover:

  • UI Macros
  • UI Formatters
  • UI Pages
  • Jelly-based dialogs
  • Custom HTML
  • g:evaluate
  • g:requires

The requirement may not be to create new Jelly. Instead, the task is to understand the existing Jelly, determine whether it is still required, and safely replace or retain it.

This is a very common maintenance scenario.

Prerequisites for Jelly Development

Before creating or modifying Jelly, verify the following:

1. Understand the User Interface

Know where the Jelly code is going to run.

Ask:

  • Is it a UI Page?
  • Is it a UI Macro?
  • Is it part of a formatter?
  • Is it being invoked from a form?
  • Is it part of an existing classic interface?

2. Understand Server-Side JavaScript

You should be comfortable with:

  • GlideRecord
  • GlideSystem
  • GlideDateTime
  • Script Includes
  • ACL concepts
  • Session/user context

3. Understand HTML

Jelly frequently generates HTML, so knowledge of:

  • HTML structure
  • attributes
  • forms
  • tables
  • CSS
  • basic JavaScript

is useful.

4. Understand Security

A Jelly page can expose sensitive information if server-side access controls are ignored.

Always consider:

  • ACL enforcement
  • user roles
  • input validation
  • record authorization
  • cross-site scripting
  • HTML escaping

Step-by-Step: Creating a Basic UI Page with Jelly

A common way to learn Jelly is to build a simple UI Page.

Step 1 – Navigate to UI Pages

Navigate to:

All → System UI → UI Pages

Select New.

The exact availability of this functionality depends on application scope and user permissions.

Step 2 – Define the UI Page

Enter a meaningful name.

Example:

request_status_page

Use a description such as:

Displays the current status of a requested item.

Step 3 – Add Jelly Code

A simple page can contain:

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="false"
    xmlns:j="jelly:core"
    xmlns:g="glide"
    xmlns:j2="null"
    xmlns:g2="null">

    <h2>Request Status</h2>

    <div>
        This page was generated using ServiceNow Jelly.
    </div>

</j:jelly>

Step 4 – Save the Page

Save the UI Page.

For development testing, use the platform’s available preview or direct page testing mechanism rather than immediately exposing the page to end users.

Step 5 – Validate the Output

Check:

  • HTML rendering
  • browser console
  • server logs
  • permissions
  • expected dynamic values

Do not assume that successful page rendering means the implementation is correct. Validate security and business behavior separately.

Step-by-Step: Using g:evaluate

One of the most frequently encountered Jelly techniques is server-side evaluation.

Example:

<g:evaluate var="jvar_message">
    var message = "Hello from the ServiceNow server";
    message;
</g:evaluate>

<div>
    ${jvar_message}
</div>

The important pattern is:

g:evaluate
     |
     v
Server-side JavaScript
     |
     v
Variable
     |
     v
Jelly/HTML output

A more practical example could retrieve a record.

<g:evaluate var="jvar_count">
    var gr = new GlideRecord('incident');
    gr.addActiveQuery();
    gr.query();
    gr.getRowCount();
</g:evaluate>

<div>
    Active incidents: ${jvar_count}
</div>

In production, however, avoid using expensive unrestricted queries merely to display a count. Apply appropriate filters and consider the performance impact.

Step-by-Step: Creating a UI Macro

UI Macros are particularly important when you need a reusable Jelly-based component.

Step 1 – Navigate to UI Macros

Navigate to:

All → System UI → UI Macros

Select New.

ServiceNow’s current documentation identifies this navigation for viewing and creating UI Macros.

Step 2 – Enter the Macro Name

Use a descriptive name.

Example:

request_status_indicator

Avoid generic names such as:

test
macro1
custom

Step 3 – Add a Description

Document:

  • Purpose
  • Expected parameters
  • Where it is used
  • Any dependencies

Example:

Displays the request status passed through the status attribute.

Step 4 – Add Jelly XML

Example:

<?xml version="1.0" encoding="utf-8" ?>
<j:jelly trim="true"
    xmlns:j="jelly:core"
    xmlns:g="glide">

    <div class="request-status">
        Status: ${jvar_status}
    </div>

</j:jelly>

Step 5 – Pass Parameters

A UI Page can invoke the macro using:

<g:request_status_indicator status="Approved" />

The UI Macro receives the attribute as:

jvar_status

This parameter-passing pattern is explicitly documented by ServiceNow for UI Macros.

Step 6 – Test

Call the macro from a controlled UI Page and verify the generated output.

If the result does not appear correctly, review:

  • Macro name
  • Attribute name
  • jvar_ variable
  • XML syntax
  • namespace declarations
  • cache

ServiceNow documentation notes that clearing the instance cache can help when a newly created UI Macro does not display as expected.

Calling UI Macros

There are several supported ways to invoke UI Macros.

For example, from a UI Page:

<g:macro_invoke macro="request_status_indicator" />

A UI Macro can also be referenced using its Jelly element when the appropriate macro is available.

ServiceNow documentation identifies UI Pages, UI Macros, and dictionary attributes as contexts from which UI Macros can be called.

This makes UI Macros useful as reusable presentation components rather than copying the same HTML and Jelly logic into multiple pages.

Testing Jelly Implementations

Testing should be performed at multiple levels.

Test 1 – Basic Rendering

Open the UI Page and confirm that:

  • The page loads.
  • Static HTML appears.
  • Dynamic variables are resolved.

Test 2 – Valid Record

Provide a valid record identifier.

Expected result:

Record information is displayed correctly.

Test 3 – Invalid Record

Use an invalid or nonexistent identifier.

Expected result:

No record found.

The page should not expose an exception or unrelated data.

Test 4 – Unauthorized User

Test using a user who does not have the required access.

Expected behavior should be determined by the application’s security model, but unauthorized information must not be exposed.

Test 5 – Performance

Test with:

  • Small dataset
  • Medium dataset
  • Larger dataset

Measure whether server-side processing becomes expensive.

Common Jelly Errors and Troubleshooting

Error 1 – Incorrect Namespace

A common mistake is using a Jelly tag without declaring its namespace.

For example, if the page uses:

<g:evaluate>

the Jelly root should include the appropriate g namespace.

Check:

xmlns:g="glide"

Error 2 – Incorrect Variable Name

If a macro receives:

status="Approved"

the UI Macro normally accesses it through:

jvar_status

not:

status

ServiceNow’s UI Macro documentation specifically describes this jvar_ convention.

Error 3 – Wrong Processing Phase

A page may contain:

g:

and:

g2:

Changing one to the other without understanding the processing model can produce unexpected behavior.

When troubleshooting existing Jelly, preserve the original processing model unless you understand why the change is required.

Error 4 – XML Syntax Error

Jelly is XML-oriented.

Common problems include:

Unclosed tags
Invalid attribute syntax
Incorrect nesting
Unescaped characters
Missing quotation marks

A single XML error can prevent the entire page from rendering.

Error 5 – UI Macro Not Appearing

Check:

  1. Macro is active.
  2. Macro name is correct.
  3. XML is valid.
  4. Parameters are correctly named.
  5. Namespace is correct.
  6. The calling page references the correct macro.
  7. Cache is refreshed where appropriate.

ServiceNow documentation notes that an inactive UI Macro does not render its defined element.

Jelly Security Considerations

Security should be treated as a primary concern.

Do Not Trust URL Parameters

Suppose a page accepts:

sys_id

from the URL.

Do not assume that the user is authorized to view that record.

A secure implementation should validate the requested record and allow the platform’s security model to control access.

Avoid Unsafe HTML Construction

If user-provided data is inserted directly into HTML, investigate escaping and output handling.

For example, never assume that a field containing user input is safe simply because it came from a ServiceNow record.

Minimize Sensitive Data

Only retrieve the fields required by the page.

Instead of querying an entire record and displaying everything, deliberately select the information required for the use case.

Common Implementation Challenges

Legacy Code

The biggest challenge with Jelly is often not writing it but maintaining existing code.

A mature ServiceNow instance may contain Jelly written by multiple developers over several years.

Before modifying it:

  1. Identify where it is used.
  2. Search for references to the UI Macro.
  3. Check whether it is part of a formatter.
  4. Review associated client-side scripts.
  5. Identify dependencies.
  6. Test the affected forms and pages.

Performance

Server-side Jelly can become expensive when it performs repeated database queries.

A poor pattern is:

Loop
  |
  +-- Query database
  |
  +-- Query database
  |
  +-- Query database

Prefer retrieving the required data efficiently and minimizing database calls.

Upgrade Impact

Classic UI customizations can be affected by platform upgrades.

Before an upgrade, inventory:

  • Custom UI Pages
  • UI Macros
  • UI Formatters
  • UI Scripts
  • Jelly references
  • Customized out-of-box components

This provides a clearer picture of potential regression areas.

Best Practices for ServiceNow Jelly

1. Use Jelly Only Where It Fits

Do not introduce Jelly into a new requirement automatically.

First determine whether the requirement can be fulfilled using a more current ServiceNow UI technology.

ServiceNow’s documentation specifically suggests considering Service Portal for developers who want to build custom interfaces using JavaScript technologies.

2. Keep UI Logic Small

Avoid turning a UI Macro into a large application.

A good macro should have a focused responsibility.

3. Reuse UI Macros

If the same UI element appears in multiple pages, consider creating a reusable macro rather than duplicating code.

4. Document Parameters

For every custom UI Macro, document:

Macro name
Purpose
Input parameters
Expected values
Calling components
Dependencies
Security considerations

5. Avoid Unnecessary Database Queries

Query only what the UI needs.

6. Validate Security

Always consider:

  • Roles
  • ACLs
  • Record access
  • Input validation
  • Output encoding

7. Test in a Sub-Production Environment

Never make an untested Jelly modification directly in production.

8. Preserve Upgradeability

Avoid modifying out-of-box components unnecessarily.

When customization is required, isolate it in custom records and document the reason.

Jelly vs Modern ServiceNow UI Development

Jelly remains useful, but it should be understood in context.

AreaJellyModern UI Approach
Classic UI PagesStrong fitDepends on requirement
Existing UI MacrosRequiredUsually not applicable
Legacy customizationCommonMigration may be possible
New user experiencesEvaluate carefullyOften preferred
Server-rendered classic UIStrongDepends on component
Reusable classic controlsUI MacrosModern components may be preferable

The important consulting decision is not simply whether Jelly works. The question is whether Jelly is the appropriate technology for the requirement and lifecycle of the application.

Practical Consultant Checklist

Before delivering a Jelly customization, verify:

  • Requirement is suitable for Jelly.

  • Existing functionality has been checked first.

  • UI Page or UI Macro has a clear purpose.

  • Namespace declarations are correct.

  • Parameters are documented.

  • jvar_ variables are correctly referenced.

  • Server-side queries are optimized.

  • Security has been validated.

  • Unauthorized access has been tested.

  • XML syntax has been validated.

  • Browser-side behavior has been tested.

  • Instance cache behavior has been considered.

  • Upgrade impact has been reviewed.

  • Customization is documented.

Frequently Asked Questions

1. Is Jelly still used in ServiceNow?

Yes. Jelly remains relevant in ServiceNow areas such as UI Pages, UI Macros, and other classic/server-rendered interface components. Existing enterprise implementations can contain substantial Jelly customization, making it important for maintenance and troubleshooting. ServiceNow documentation continues to document UI Macros and their relationship with Jelly.

2. What is the difference between Jelly and JavaScript?

JavaScript is a programming language, while Jelly is an XML-based templating and processing technology. In ServiceNow, Jelly can execute or incorporate server-side JavaScript and use ServiceNow-specific tags to generate dynamic UI content.

For example, g:evaluate can be used to evaluate server-side JavaScript within Jelly.

3. What is jvar_ in ServiceNow Jelly?

jvar_ variables are commonly used by UI Macros to access attributes passed to the macro.

For example:

<g:ui_example status="Approved" />

can expose the attribute inside the macro as:

jvar_status

This pattern is documented by ServiceNow for passing UI Macro attributes.

Summary

ServiceNow Jelly is an important technology for understanding the platform’s classic server-rendered user interface architecture. It is especially relevant when working with UI Pages, UI Macros, UI Formatters, and legacy customizations.

The most important concepts to understand are Jelly namespaces, processing phases, ServiceNow-specific g: tags, server-side evaluation, UI Macro parameter handling, and the relationship between Jelly and generated HTML.

From an implementation perspective, the biggest lesson is that Jelly should be treated as a platform UI technology rather than simply another scripting language. Good Jelly development requires an understanding of ServiceNow security, database access, XML syntax, server-side processing, user-interface behavior, and upgrade impact.

For new development, evaluate the current ServiceNow UI capabilities before choosing Jelly. For existing enterprise applications, however, strong Jelly knowledge can significantly reduce troubleshooting time and make legacy customizations much easier to maintain.

For additional reference, consult the current ServiceNow product documentation and specifically review the documentation for UI Pages, UI Macros, Jelly tags, and custom UI Pages/UI Macros before implementing production changes.


Share

Leave a Reply

Your email address will not be published. Required fields are marked *