Releases: ServiceNow/sdk
SDK 4.5.0
@servicenow/sdk — Release Notes
Version: 4.5.0
Availability: npm — https://www.npmjs.com/package/@servicenow/sdk
🚀 Overview
Version 4.5.0 adds new Fluent APIs and fixes some more bugs!
New Fluent APIs
Instance Scan Records
New APIs are available for configuring Instance Scan checks for detecing anomalies on your instance.
Scheduled Script
The ScheduledScript (sysauto_script) API can be used to execute custom scripst at specified times or on a recurring basis.
ServicePortal
More APIs have been added for creating Service Portal items to round out the existing Fluent APIs that already exist.
SPPagefor creating pagesSPThemefor creating themesSPWidgetfor creating widgetsSPMenufor creating menus
Now Assist Skill Kit
Adds a Fluent API NowAssistSkillConfig for creating NowAssist Skill configurations
AI Agent Studio
The addition of Fluent AI Agent Studio Fluent APIs enable the create and manage AI agents and workflows!
- Adds new Fluent APIs
AiAgentfor creating AI Agent definitions - Adds new Fluent API
AiAgentWorkflowthat allows for creating dynamic agentic workflow definitions
New Features
Flows
- All Flows and Subflows installed from the SDK will now be auto published as part of now-sdk
install. Use flag-skip-flow-activationto disable this if needed. - NOTE: This requires version
4.1.1or later of the ServiceNow IDE installed on your instance.
Changes
- Removed eslint dependency from projects and updated internal reference to v9. After upgrading to
4.5.0of@servicenow/sdkyou can remove the dependency on@servicenow/eslint-plugin-sdk-app-pluginfrom your projects package.json initcommand no longer prompts for credentials unless converting from the instance- Fix metadata folder content copy for binary files being copied as utf8
FieldListColumnaccepts eitherdependentorattributes.table- Fix
EmailNotificationnot correctly escaping encoded values - Fix CatalogItem checkbox selection required field mapping missing
- Fix dev server watching HTML and CSS asset files
- Fix unable to create global app with UI customizations
- Flow fixes:
setFlowVariabletransform issues- SubFlow complex object transform issues
- Trigger
createOrUpdateconverting to wrong type on transform - Flow
runAsdefaulting touserinstead ofsystem - Issues with diagnostic errors on
setFlowVariablesnot working
SDK 4.4.0
@servicenow/sdk — Release Notes
Version: 4.4.0
Availability: npm — https://www.npmjs.com/package/@servicenow/sdk
🚀 Overview
Version 4.4.0 fixes some bugs and adds a new dev server capability for front end UI building with the SDK, and some internal support for future version of Build Agent and Australia release for global app support!
New Features
Front-End Dev Server
A highly requested feature — the dev server drastically reduces build cycles and enables rapid UI development without needing to deploy to an instance. Requests are proxied to the ServiceNow instance defined in your auth credentials.
Note: Dev server scripts are included in new projects only. A future release will add a command to install it into existing projects.
Getting started:
- Run
sdk initusing thereactorvuetemplate - Start the server with
npm run dev
Requirements:
@servicenow/isomorphic-rollup>=1.2.14@servicenow/sdk>=4.4.0now.dev.mjspresent in your project (generated duringinit)
ServiceCatalog & Flows
Add support between Flows and ServiceCatalog in Fluent for interacting with catalog variables and actions in Flows, and for Catalog Items to trigger Flows!
- Support for Flow Service Catalog Item triggers
- Support for
getCatalogVariablesaction in Flows - Support for `createCatalogTask' action in Flows
- Support for
submitCatalogItemRequestaction in Flows
Changes
- Fix invalid transformation for
durationfield forSla - Fix
requestMethodonCatalogItemandCatalogItemProducernot serializing properly - Stable UX asset IDs (will see keys.ts location changes)
- Add
protectionPolicytoACL - Add
tableDefaultLanguagetonow.config.jsonto support setting language on table column labels - Fix APIs that were not restricting arbitrary properties!
NOTE: Many APIs were not strictly enforcing that extra properties could not be defined on the API, which caused some usage errors around mispelling properties or thinking they can add a property and it will be added to the build output, and should be fixed or removed.
For example this would not produce an error:
Property({
$id: Now.ID['property-1'],
name: 'x_foo.myproperty',
randomProperty: true
})This will now produce an error diagnostic that randomProperty does not exist as an option on Property! This may introduce a build error for existing projects when upgrading to 4.4.0, but these properties were being ignored during build causing false positives.
SDK 4.3.0
@servicenow/sdk — Release Notes
Version: 4.3.0
Availability: npm — https://www.npmjs.com/package/@servicenow/sdk
🚀 Overview
Version 4.3.0 introduces the highly anticipated Flow API, significant build and transform performance improvements, expanded Service Catalog support, and several new platform capabilities.
This release focuses on enabling workflow-as-code, improving developer productivity, and strengthening type safety across UI and automation development.
🎊 New Fluent APIs
Flow API (MVP)
The Flow API enables building ServiceNow workflows entirely in code using Fluent. Please try this out if you are a Flow user, and give us feedback in the discussions area, we plan to keep enhancing Flows in the next few releases!
Benefits include:
- Workflow-as-code
- AI-assisted development
- Pull request reviews
- Standardized development workflows
Supported Capabilities
Flow Definition
- Name, description, runAs
- Flow priority and protection
- Typed flow variables
Triggers
- Record:
created,updated,createdOrUpdated - Scheduled:
daily,weekly,monthly,repeat,runOnce - Application:
inboundEmail,remoteTableQuery,knowledgeManagement,slaTask
Actions
- Record CRUD operations
- Communication (email, SMS, notifications, approvals)
- Attachment management
- Email utilities
- Core utilities and task automation
Flow Logic
- Conditional branching (
if,elseIf,else) - Loops (
forEach,exitLoop,skipIteration) - Variable management
- Flow control and delays
Data & Types
wfa.dataPill()data referencing- Full TypeScript type safety
- Reference dot-walking support
MVP Limitations
The following capabilities are planned for future releases:
- ❌ Subflow invocation
- ❌ Try/Catch error handling
- ❌ Step rewind (Go-Back-To)
- ❌ Service Catalog trigger
- ❌ Catalog actions
- ❌ DateTime flow variables (use
StringColumnworkaround)
Example
An incident severity alert flow — triggers on incident creation, branches by severity, notifies stakeholders, and sets state to In Progress.
import { action, Flow, wfa, trigger } from '@servicenow/sdk/automation'
export const incidentSeverityAlertFlow = Flow(
{
$id: Now.ID['incident_severity_alert_flow'],
name: 'Incident Severity Alert Flow',
description: 'Notifies team based on incident severity and sets state to In Progress',
},
wfa.trigger(
trigger.record.created,
{ $id: Now.ID['incident_created_trigger'] },
{ table: 'incident', condition: 'origin=NULL', run_flow_in: 'background' }
),
(params) => {
// Log the new incident
wfa.action(
action.core.log,
{ $id: Now.ID['log_incident'] },
{
log_level: 'info',
log_message: `New incident: ${wfa.dataPill(params.trigger.current.short_description, 'string')}`,
}
)
// High severity — notify manager + SMS all assignees
wfa.flowLogic.if(
{
$id: Now.ID['check_high'],
condition: `${wfa.dataPill(params.trigger.current.severity, 'string')}=1`,
},
() => {
wfa.action(
action.core.sendNotification,
{ $id: Now.ID['notify_manager'] },
{
table_name: 'incident',
record: wfa.dataPill(params.trigger.current.sys_id, 'reference'),
notification: 'high_severity_manager_notification',
}
)
wfa.flowLogic.forEach(
wfa.dataPill(params.trigger.current.additional_assignee_list, 'array.string'),
{ $id: Now.ID['foreach_assignees'] },
() => {
wfa.action(
action.core.sendSms,
{ $id: Now.ID['sms_assignee'] },
{
recipients: wfa.dataPill(params.trigger.current.additional_assignee_list, 'array.string'),
message: `High severity: ${wfa.dataPill(params.trigger.current.short_description, 'string')}`,
}
)
}
)
}
)
// Medium severity — SMS assignees only
wfa.flowLogic.elseIf(
{
$id: Now.ID['check_medium'],
condition: `${wfa.dataPill(params.trigger.current.severity, 'string')}=2`,
},
() => {
wfa.flowLogic.forEach(
wfa.dataPill(params.trigger.current.additional_assignee_list, 'array.string'),
{ $id: Now.ID['foreach_assignees_medium'] },
() => {
wfa.action(
action.core.sendSms,
{ $id: Now.ID['sms_assignee_medium'] },
{
recipients: wfa.dataPill(params.trigger.current.additional_assignee_list, 'array.string'),
message: `Medium severity: ${wfa.dataPill(params.trigger.current.short_description, 'string')}`,
}
)
}
)
}
)
// Always set state to In Progress
wfa.action(
action.core.updateRecord,
{ $id: Now.ID['update_state'] },
{
table_name: 'incident',
record: wfa.dataPill(params.trigger.current.sys_id, 'reference'),
values: TemplateValue({ state: '2' }),
}
)
}
)🧾 Service Catalog Enhancements
Added support for Service Catalog and supporting entities:
- Catalog Client Scripts (
catalog_script_client) - Catalog Items (
sc_cat_item) - Catalog UI Policies (
catalog_ui_policy) - Catalog Variables (
item_option_new) - Variable Sets (
item_option_new_set) - Record Producers (
sc_cat_item_producer)
Catalog Variables
Fluent provides 31 different types of catalog variables to support a wide range of form input needs. Each variable type has a specific function that creates a properly configured variable object.
Example
CatalogItem({
$id: Now.ID['basic_catalog_item'],
name: 'Basic Laptop Request',
shortDescription: 'Request a standard laptop for business use',
description: 'Use this form to request a standard laptop for business use. Approval from your manager is required.',
catalogs: [catalogServiceCatalog],
categories: [categoryHardware],
variableSets: [{ variableSet: userInfoVarSet, order: 100 }],
executionPlan: '523da512c611228900811a37c97c2014',
})
CatalogClientScript({
$id: Now.ID['new-laptop-client-script'],
name: 'Required By Date Validation',
script: `function onSubmit() {
var reqDate = g_form.getValue('required_by_date');
var today = new Date();
var selectedDate = new Date(reqDate);
var diffDays = (selectedDate - today) / (1000 * 60 * 60 * 24);
if (diffDays < 7) {
alert('Required By date must be at least 7 days from today.');
return false;
}
return true;
}
`,
type: 'onSubmit',
catalogItem: requestNewLaptop,
appliesOnRequestedItems: true,
appliesOnCatalogTasks: true,
appliesOnTargetRecord: true,
vaSupported: true,
})
VariableSet({
$id: 'contact_info_set',
title: 'Contact Information',
internalName: 'contact_information',
description: 'Standard contact information fields including phone, email, and address',
type: 'singleRow',
order: 100,
})
CatalogUIPolicy({
$id: Now.ID['employee_request_ui_policy_external_1'],
shortDescription: 'If urgent is true, require manager approval and show department',
catalogCondition: `${departmentVariableSet.variables.urgent} === true`,
variableSet: departmentVariableSet,
appliesTo: 'set',
actions: [
{
variableName: departmentVariableSet.variables.department,
order: 100,
mandatory: true,
visible: true,
}
],
});
CatalogItemRecordProducer({
$id: Now.ID['basic_incident_producer'],
name: 'Report an Incident',
shortDescription: 'Create a new incident ticket',
description: '<p>Use this form to report IT issues and incidents.</p>',
table: 'incident',
catalogs: [catalogServiceCatalog],
categories: [categoryIncidents],
variableSets: [
{ variableSet: incidentDetailsVarSet, order: 100 },
],
hideSaveAsDraft: false,
mandatoryAttachment: false,
hideAttachment: true,
availableFor: [userCriteriaITStaff],
})Email Notification
Creates an Email Notification (sysevent_email_action) in ServiceNow.
import { EmailNotification } from '@servicenow/sdk/core'
EmailNotification({
table: 'incident',
name: 'Incident Assigned Notification',
description: 'Notification sent when an incident is assigned',
triggerConditions: {
generationType: 'engine',
onRecordInsert: true,
onRecordUpdate: true,
condition: 'assigned_toISNOTEMPTY'
},
recipientDetails: {
recipientFields: ['assigned_to'],
sendToCreator: false
},
emailContent: {
contentType: 'text/html',
subject: 'Incident ${number} assigned to you',
messageHtml: '<p>You have been assigned incident ${numb...SDK 4.2.0
Available on npm at @servicenow/sdk
What's New in v4.2
Version 4.2 introduces powerful new Fluent APIs, enhanced type safety for server-side development, and improved developer tooling. This release focuses on making ServiceNow application development more intuitive and type-safe.
🚀 New Features
ImportSet Fluent API
The ImportSet API provides a fluent interface for creating Transform Maps with their associated field mappings (sys_transform_entry) and transform scripts (sys_transform_script).
Note: Data Sources (sys_data_source) should be configured through the Record API, as they contain structurally flat, independent metadata.
Basic Configuration
ImportSet({
$id: Now.ID['user-import-set'],
name: 'User Data Import',
targetTable: 'sys_user',
sourceTable: 'u_user_import_staging',
active: true,
runBusinessRules: true,
enforceMandatoryFields: 'onlyMappedFields',
fields: {
first_name: 'name',
last_name: 'last_name',
email: {
sourceField: 'email',
coalesce: true,
coalesceCaseSensitive: false
}
}
})Advanced Configuration with Field Transforms
ImportSet({
$id: Now.ID['advanced-import-set'],
name: 'Advanced User Import',
targetTable: 'sys_user',
sourceTable: 'u_user_import_staging',
active: true,
runScript: true,
script: transformUserData, // Imported function
fields: {
email: {
sourceField: 'email_address',
coalesce: true,
useSourceScript: true,
sourceScript: `answer = (function transformEntry(source) {
return source.email_address.toLowerCase().trim();
})(source);`
},
department: {
sourceField: 'dept_code',
choiceAction: 'create'
}
},
scripts: [
{
active: true,
order: 100,
when: 'onBefore',
script: `(function runTransformScript(source, map, log, target) {
if (!source.email_address || source.email_address.indexOf('@') === -1) {
log.error('Invalid email address: ' + source.email_address);
return;
}
})(source, map, log, target);`
}
]
})UiPolicy Fluent API
Configure UI Policy records (sys_ui_policy) with their associated UI Policy Actions (sys_ui_policy_action) and Related List Actions (sys_ui_policy_rl_action) to control field visibility, mandatory status, read-only behavior, and related list visibility on forms.
Basic UI Policy
UiPolicy({
$id: Now.ID['incident_related_list_control'],
table: 'incident',
shortDescription: 'Control related lists for high priority incidents',
onLoad: true,
conditions: 'priority=1',
actions: [
{
field: 'urgency',
mandatory: true
}
],
relatedListActions: [
{
$id: Now.ID['rl_action_1'],
list: 'b9edf0ca0a0a0b010035de2d6b579a03', // System relationship (GUID)
visible: false
},
{
$id: Now.ID['rl_action_2'],
list: 'incident.caller_id', // table.field format (reference field)
visible: true
},
{
$id: Now.ID['rl_action_3'],
list: 'change_request.change_task', // Parent-child relationship
visible: 'ignore'
}
]
})UI Policy with Scripts
UiPolicy({
$id: Now.ID['task_assignment_policy'],
table: 'task',
shortDescription: 'Task assignment validation with scripts',
onLoad: true,
conditions: 'assigned_to=',
runScripts: true,
scriptTrue: `function onCondition() {
g_form.addInfoMessage('Please assign this task to a user.');
g_form.setMandatory('assigned_to', true);
}`,
scriptFalse: `function onCondition() {
g_form.clearMessages();
}`,
uiType: 'desktop',
isolateScript: true,
actions: [
{
field: 'assigned_to',
mandatory: true
}
]
})Now.attach API for Image Fields
Attach images to Image field type columns.
import { Record } from '@servicenow/sdk/core'
Record({
$id: Now.ID['test'],
table: 'sp_portal',
data: {
title: 'Test Portal',
url_suffix: 'test',
icon: Now.attach('../../assets/servicenow.jpg')
}
})Additional Column Types
The Table API now supports additional database column types:
Password2ColumnGuidColumnJsonColumnNameValuePairsColumnUrlColumnEmailColumnHTMLColumnFloatColumnMultiLineTextColumnDurationColumnTimeColumnFieldListColumnSlushBucketColumnTemplateValueColumnApprovalRulesColumn
Utility Helper Functions
The SDK now includes helper functions for complex ServiceNow data types, providing strong typing support and simplified syntax.
Duration()
Works with the DurationColumn type for specifying duration values in days, hours, minutes, and seconds.
Record({
table: 'u_my_table',
data: {
duration_field: Duration({ days: 1, hours: 6, minutes: 30, seconds: 15 })
}
})Time()
Works with the TimeColumn type for specifying times in hours, minutes, and seconds.
Record({
table: 'u_my_table',
data: {
time_field: Time({ hours: 6, minutes: 30, seconds: 15 }), // Basic example
time_tz_field: Time({ hours: 6, minutes: 30, seconds: 15 }, 'America/New_York') // With timezone
}
})FieldList()
Works with the FieldListColumn type for specifying a list of field names that are type-checked to a specified table, with dot-walking support.
Record({
table: 'u_my_table',
data: {
field_list_field: FieldList<'sys_user'>(['name', 'company', 'active', 'manager.name'])
}
})TemplateValue()
Works with the TemplateValueColumn type for specifying objects with field-value pairs.
Example TemplateValue in encoded format: cost=100^description=Catalog Item Description^category=Hardware^active=true^EQ
Record({
table: 'u_my_table',
data: {
template_field: TemplateValue({
cost: 100,
description: 'Catalog Item Description',
category: 'Hardware',
active: true,
})
}
})Enhanced dependencies Command
When developing ServiceNow applications, having complete type information for instance dependencies outside your app scope is essential for type safety and better developer experience. The dependencies command now provides enhanced support for pulling down type definitions for tables and roles.
Configuration
Configure dependencies through the now.config.json file:
{
"dependencies": {
"global": {
"tables": [
"cmdb_ci_server"
],
"roles": [
"admin",
"itil"
]
}
}
}Fluent API Type Imports
Fluent code dependencies are now stored in the local @types folder at @types/servicenow/fluent and can be referenced using the #now:{scope}/{category} import alias pattern that is configured through package.json.
For existing projects: Manually add the following imports configuration to your package.json (this is automatically configured for new projects):
{
"imports": {
"#now:*": "./@types/servicenow/fluent/*/index.js"
}
}Usage example:
import { Acl } from "@servicenow/sdk/core";
import { role as globalRole } from "#now:global/security";
Acl({
$id: Now.ID["my_acl"],
type: "record",
table: "incident",
operation: "read",
roles: [globalRole.admin, globalRole.itil],
});Server Script Type Definition Enhancements
Version 4.2 significantly improves type safety for server-side module development. The @servicenow/glide package (v27.0.3+) now includes generic support for GlideRecord, GlideElement, and GlideRecordSecure, enabling proper table-aware type checking.
Migration for Existing Projects
To take advantage of enhanced type definitions:
- Update the
@servicenow/glidepackage:
{
"dependencies": {
"@servicenow/glide": "27.0.3"
}
}- Run the dependencies command:
now-sdk dependencies- Update
src/server/tsconfig.json:
{
"include": [
"../../@types/**/*.modules.d.ts"
]
}Result
Module files now provide rich type information for GlideRecord calls for any table on your instance:
Type Definitions for Server Scripts Using Now.include
Enhanced type support for server scripts such as script includes, business rules, and other non-module scripts is now available when using Now.include and can take advantage of the type definitions if the @types folder as well. To connect these Typescript definitions to your code, we suggest using a .server.js type file extension pattern for any server side code, and .client.js for client side javascript.
Examp...
SDK 4.1.1
Available on npm at @servicenow/sdk
This is a minor patch release to fix some issues with module dependencies, and address some dependency vulnerabilities
Fixes:
- Support third party modules that are imported using trailing slashes Ex. require('buffer/') which are now supported in glide
- Support for declaring a dependency on libraries that are named the same as node_builtins in order to use those libraries on the platform
- Fix
criticalandhighseverity vulnerabilities in some 3rd party dependencies
SDK 4.1.0
Availalbe on npm at @servicenow/sdk
🚀 New Features
Module Include/Exclude File Patterns
-
Added support for specifying include and exclude file patterns during module builds.
-
Useful for omitting test files or other support files from being treated as module files.
-
New
now.config.jsonproperties:serverModulesIncludePatternsserverModulesExcludePatterns
Default patterns:
// Include defaults
"**/*.ts",
"**/*.tsx",
"**/*.js",
"**/*.jsx",
"**/*.cts",
"**/*.cjs",
"**/*.mts",
"**/*.mjs",
"**/*.json"
// Exclude defaults
"**/*.test.ts",
"**/*.test.js",
"**/*.d.ts"Apply Templates to Existing Projects
- Running
initinside an existing SDK project now prompts for template selection. - Enables applying UI templates and others to already initialized projects.
Script Include Type Generation for Modules
- The
dependenciescommand now scans modules for scope definitions and fetches script-include types from the instance. - Types are saved under
@types/servicenow. - Detection is based on subpath imports under the
@servicenow/glidenamespace like@servicenow/glide/[scope].
Example:
import { global } from "@servicenow/glide/global";
function test() {
const utils = new global.UtilScript();
const tables = utils.getTables("cmdb_ci_server");
}🐛 Fixes
- Fixed
Listrecords not being deleted on build when fluent code is removed. - Ignored
type-only imports in sys modules during dependency generation. - Fixed
UiActiononClickproperty being cleared on the instance. - Added diagnostics for missing
.htmlfile imports. - Ensured
$meta.installMethodis respected on child records during build. - Fixed
lstaterrors when using certain 3rd-party front-end dependencies (e.g.,@mix/x-charts). - Corrected ATF
Testsys_scopenot being set properly during build. - Fixed radio column choices not being populated during transform.
- Corrected
ClientScriptdiagnostic errors fortype = 'onChange' | 'onLoad'whenfieldis set. - Fixed multiple transform issues with
UiPolicy. - Fixed build failures when fluent content includes XML CDATA escape sequences (
]]>). - Ensured
priorityis captured correctly duringBusinessRuletransform.
SDK 4.0.2
This is a patch release for @ServiceNow/sdk version 4.0.2
- Fix an issue with the front end framework development build system on the ServiceNow IDE
SDK 4.0.1
This is a patch release for @servicenow/sdk version 4.0.1
Changes:
- Fix ATF
Testserialization of record arrays on steps - Fix empty SDK version when using
initon Windows systems - Fix
deployalways reporting success and not checking upgrade history properly - Fix
Tablenot supporting customizing tables viaas anyescape on table name. For example if you wish to add a column to thetasktable you would use theTableAPI and cast the table nameas anyto silent the diagnostic error for thenameproperty. - Moved React dependencies to
devDependenciesin init templates - Fix UI client build failures on Windows
- Fix
$meta.installMethodnot being respected by child records - Fix
ClientScriptfailing build when type is set toonSubmit | onLoadwhenfieldis set
Table({
name: 'task' as any
schema: {
x_mycolumn: new StringColumn({...})
}
})SDK 4.0.0
🔥 4.0.0 is here! 🔥
The latest release of the @servicenow/sdk just dropped on npm, and it’s a big one.
Internally, we’ve completely overhauled our plugin framework to make APIs more reliable, and way faster to ship. Translation? You’ll be seeing more APIs, more often 🚀.
But the real star of the show:
- ⚛️ Front-End app support with front end frameworks like React, Vue, Svelte, SolidJS, and others!
- ⚡️ New Fluent APIs to level up your applications development
- 🛠️ A rock-solid foundation for even bigger things coming soon
Check out the release notes below, kick the tires, and drop your thoughts on the discussion board. We can’t wait to see what you build with 4.0.0 🙌.
New Fluent APIs
Some new Fluent APIs have been added to make working with certain types of tables easier using the SDK.
- ScriptInclude (sys_script_include)
- UiPage (sys_ui_page)
- UiAction (sys_ui_action)
- ScriptAction (sysevent_script_action)
- ServicePortal elements
- SpWidget (sp_widget)
- SPWidgetDependency (sp_dependency)
- SpAngularProvider (sp_angular_provider)
Command changes
There are some minor command changes to now-sdk and they can be viewed using --help option for more information.
-
Added
cleancommand
The clean command will clean out the build output directory, typically dist folder. This is automatically performed as part of the build command, but if you have any other needs to clean out the folder you can use this command. -
Added
packcommand
The pack command will package up the output of a build into an installable archive file. pack is automatically performed as part of the install command. Pack used to be run at the end of build but this was removed since installalso performs pack -
Added
downloadcommand
The download command can be used for downloading complete or incremental metadata from the instance for the application.
Front-end framework support
The SDK now supports building front-end applications with standard frameworks to run on ServiceNow! For this first release, we are natively supporting React out of the box, and we are aiming to support a "bring your own front end" (BYOF) approach. This new feature will let you use a more modern development experience for building UI applications.
To get started building front ends, simply choose a template with included front-end framework support such as now-sdk + fullstack React when running init to get started!
This is just the beginning of the BYOF support we are adding to the SDK and we will be following up soon with more support for providing your own bundler and tooling for other frameworks like Svelte, Vue, etc...
How does it work?
Front-end applications utilize the UiPage Fluent API for bundling and hosting the application and its entry point. The SDK detects importing from an .html page that is being assigned to the html attribute on UiPage Fluent API and bundles your front end into static assets served with your application.
By default, the front-end application code lives in your src/client directory (configurable in now.config.json with the clientDir property). Add all your images, style sheets, fonts, etc. here the same way you would for any typical React application that you're building. The out of the box bundler we have included is Rollup to package up the your front end application.
Example with React:
import { UiPage } from '@servicenow/sdk/core'
import indexPage from '../client/index.html'
UiPage({
$id: Now.ID['sample-frontend'],
endpoint: 'x_sampleapp-uipage-fe.do',
description: 'Sample Front-End Application',
category: 'general',
html: indexPage,
direct: true,
})In the src/client folder create an index.html page like this:
<html>
<head>
<title>Sample Front-End Application</title>
<!-- Initialize globals and Include ServiceNow's required scripts -->
<sdk:now-ux-globals></sdk:now-ux-globals>
<!-- Include your React entry point -->
<script src="./main.tsx" type="module"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>In the src/client/* folder add a main.tsx file with your React code, CSS, and other assets to build your application
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './app'
const rootElement = document.getElementById('root')
if (rootElement) {
ReactDOM.createRoot(rootElement).render(
<React.StrictMode>
<App />
</React.StrictMode>
)
}When you are ready, just build and install then open the UI Page on the instance to view your application!
- React Sample: https://github.com/ServiceNow/sdk-examples/tree/main/react-ui-page-ts-sample
- Svelte Sample: https://github.com/ServiceNow/sdk-examples/tree/main/svelte-ui-page-sample
- Vue Sample: https://github.com/ServiceNow/sdk-examples/tree/main/vue-ui-page-sample
- SolidJS Sample: https://github.com/ServiceNow/sdk-examples/tree/main/solidjs-ui-page-sample
Limitations:
- Only hash routing is currently supported by UI Pages.
- Maximum file size of assets is limited to the
com.glide.attachment.max_sizesystem property - Preloading content linked from HTML isn't supported
(rel="preload") - Relative style sheets linked from HTML aren't supported
(rel="stylesheet"). Import your style sheets into code instead (import "path/to/style-sheet") - Relative
@importin CSS isn't supported - CSS modules aren't supported
- Server-side rendering and React server components aren't supported
API Changes
ListAPI deprecates $id property as it is a coalescing table and uses combination of name, view, sys_domain, element, relationship, and parent properties. The property will not produce build errors but be marked as deprecated.RoleAPI deprecates $id property as it is a coalescing table and uses the name property to generate its key. The property will not produce build errors but will be marked as deprecated.ClientScriptAPI will no longer produce script fields with tagged template literalsscript tag during generation by default. Syntax highlighting for these tags were removed back in 3.0 in favor of Now.include functionality. The tags will not produce build errors, and they do not alter functionality.
//Before
ClientScript({
script: script`gs.info("hello world")`
...
})
//After
ClientScript({
script: `gs.info("hello world")`
...
}) Breaking Changes
- Custom properties have been removed in this version. In versions 3.0 and earlier, you could specify custom properties not included in the type definition on any API. This was helpful for setting custom fields on out-of-box table definitions. However, this feature has been removed in 4.0 to prevent issues caused by allowing arbitrary properties in the API type. This feature would cause AI hallucinations during code generation due to lack of strict type checking on the arbitrary fields that were allowed. We are planning to bring this back soon (4.1+), so if you rely on this in your application please wait or alternatively use the
RecordAPI instead if that's a possibility.
For example, you could specify a field called x_customfield on an API like Role in version 3.0 and prior and that field would be automatically added to the build output.
Role({
$id: Now.ID['my_id'],
name: 'x_myapp_rolename',
x_customfield: 'some value'
}) Documentation
Support and Issues
SDK 3.0.3
📢 We are pleased to announce the release of 3.0.3 of the @servicenow/sdk is available for download on npm!
This is a minor patch release that fixes a bug in the SDK
Fixes
- Table columns that defined
dynamic_value_definitions.calculated_valuefields withstringvalues were creating invalid xml. This did not affect using module imports on thecalculated_valuefield.
Example:
StringColumn({
label: "Label Name",
dynamic_value_definitions: {
type: "calculated_value",
calculated_value: `javascript:global.getNextObjNumberPadded();`,
},
}),