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:
| Component | Typical Jelly Usage |
|---|---|
| UI Pages | Complete custom pages and dialogs |
| UI Macros | Reusable UI controls |
| UI Formatters | Adding custom elements to forms |
| Dictionary attributes | Referencing certain UI Macros |
| Classic UI components | Server-rendered interface elements |
| Custom dialogs | Dynamic dialog content |
| Legacy customizations | Existing 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 interfaceThis 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.
| Tag | Purpose |
|---|---|
<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:
- Receive a record identifier.
- Retrieve the record.
- Validate access.
- Display relevant fields.
- Generate approval actions.
- 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_typeUse 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:evaluateg: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:
GlideRecordGlideSystemGlideDateTime- 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_pageUse 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 outputA 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_indicatorAvoid generic names such as:
test
macro1
customStep 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_statusThis 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_statusnot:
statusServiceNow’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 marksA single XML error can prevent the entire page from rendering.
Error 5 – UI Macro Not Appearing
Check:
- Macro is active.
- Macro name is correct.
- XML is valid.
- Parameters are correctly named.
- Namespace is correct.
- The calling page references the correct macro.
- 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_idfrom 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:
- Identify where it is used.
- Search for references to the UI Macro.
- Check whether it is part of a formatter.
- Review associated client-side scripts.
- Identify dependencies.
- 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 databasePrefer 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 considerations5. 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.
| Area | Jelly | Modern UI Approach |
|---|---|---|
| Classic UI Pages | Strong fit | Depends on requirement |
| Existing UI Macros | Required | Usually not applicable |
| Legacy customization | Common | Migration may be possible |
| New user experiences | Evaluate carefully | Often preferred |
| Server-rendered classic UI | Strong | Depends on component |
| Reusable classic controls | UI Macros | Modern 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_statusThis 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.