@servicenow/sdk
Version:
ServiceNow SDK
236 lines (172 loc) • 6.1 kB
Markdown
---
tags: [SPWidget, service portal, widget, sp_widget]
---
# SPWidget
Creates a Service Portal widget — a self-contained AngularJS component with its own server script, client controller, HTML template, and CSS (`sp_widget`). Widgets are the building blocks of Service Portal pages, handling data fetching, user interaction, and rendering.
## Signature
```typescript fluent
SPWidget(config)
```
## Parameters
### config
`SPWidget<keyof Tables>`
**Properties:**
- **$id** (required): `string | number | ExplicitKey<string>`
- **name** (required): `string`
The name of the widget (required)
- **$meta** (optional): `object`
- **installMethod**: `'first install' | 'demo' | 'once'`
Map a record to an output folder that loads only in specific circumstances.
'first install' - > 'unload',
'demo' -> 'unload.demo'
- **angularProviders** (optional): `(string | Record<'sp_angular_provider'> | SPAngularProvider)[]`
Array of Angular providers for the widget
- **category** (optional): `'standard' | 'custom' | 'sample' | 'otherApplications' | 'knowledgeBase' | 'servicePortal' | 'serviceCatalog'`
The category of the widget (default is 'custom')
- **clientScript** (optional): `string`
The client script for the widget
- **controllerAs** (optional): `string`
The controller for the widget (default is 'c')
- **customCss** (optional): `string`
The custom CSS for the widget
- **dataTable** (optional): `Table`
The data table for the widget (default is 'sp_instance')
- **demoData** (optional): `JsonSerializable`
The demo data for the widget
- **dependencies** (optional): `(string | SPWidgetDependency | Record<'sp_dependency'>)[]`
Array of widget dependencies
- **description** (optional): `string`
The description of the widget
- **docs** (optional): `string | Record<'sp_documentation'>`
The documentation for the widget
- **fields** (optional): `(string | SystemColumns | keyof FullSchema<Table>)[]`
The fields for the widget
- **hasPreview** (optional): `boolean`
Show the preview pane in the Service Portal editor
- **htmlTemplate** (optional): `string`
The HTML template for the widget
- **id** (optional): `string`
The unique id for the widget. Must contain alphanumeric, -, or _ characters
- **internal** (optional): `boolean`
internal field used by ServiceNow developers
- **linkScript** (optional): `string`
The link script for the widget (client-side)
- **optionSchema** (optional): `WidgetOption[]`
The option schema for the widget
- **public** (optional): `boolean`
Whether the widget is public
- **roles** (optional): `(string | Role | Record<'sys_user_role'>)[]`
The roles that can access the widget
- **serverScript** (optional): `string`
The server script for the widget
- **servicenow** (optional): `boolean`
Built by ServiceNow. On build, can only be true if scope has sn_ or snc_ prefix
- **templates** (optional): `SPTemplate[]`
Array of widget templates
## Examples
### Service Portal Widget with External Files
Create a widget with external client script, server script, HTML template, and CSS
```typescript fluent
/**
* @title Service Portal Widget with External Files
* @description Create a widget with external client script, server script, HTML template, and CSS
*/
import { SPWidget } from '@servicenow/sdk/core'
// Chart.js dependency sys_id (ServiceNow-provided library)
const CHARTJS = 'a7a8754347011200ba13a5554ee4905c'
SPWidget({
$id: Now.ID['sample-widget'],
name: 'Sample Widget',
id: 'sample-widget',
clientScript: Now.include('../../server/SPWidget/sample-widget.client.js'),
serverScript: Now.include('../../server/SPWidget/sample-widget.server.js'),
htmlTemplate: Now.include('../../server/SPWidget/sample-widget.html'),
customCss: Now.include('../../server/SPWidget/sample-widget.scss'),
demoData: {
data: {
incidents: [99, 59, 80, 81, 56, 55, 40, 0, 5, 21, 11, 30],
},
},
hasPreview: true,
dependencies: [CHARTJS],
})
```
**sample-widget.client.js**
```javascript
function controller() {
this.onClick = () => {
console.log('Widget clicked')
}
}
```
**sample-widget.server.js**
```javascript
;(() => {
data.message = 'Hello from the widget server script'
})()
```
**sample-widget.html**
```javascript
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Sample Widget</h3>
</div>
<div class="panel-body">
<p>Hello from the widget</p>
</div>
</div>
```
**sample-widget.scss**
```javascript
.panel {
margin: 10px;
border-radius: 4px;
}
.panel-heading {
background-color: #f5f5f5;
}
.panel-body {
padding: 15px;
}
```
### Widget with Inline Content
Create a Service Portal widget with inline HTML template and scripts
```typescript fluent
/**
* @title Widget with Inline Content
* @description Create a Service Portal widget with inline HTML template and scripts
*/
import { SPWidget } from '@servicenow/sdk/core'
SPWidget({
$id: Now.ID['inline-widget'],
name: 'Inline Widget',
id: 'inline-widget',
htmlTemplate: '<div class="panel">{{data.message}}</div>',
serverScript: Now.include('./server-script.js'),
clientScript: Now.include('./client-script.js'),
hasPreview: false,
})
```
### Widget with Angular Providers
Create a Service Portal widget that uses custom Angular directives
```typescript fluent
/**
* @title Widget with Angular Providers
* @description Create a Service Portal widget that uses custom Angular directives
*/
import { SPWidget, SPAngularProvider } from '@servicenow/sdk/core'
const myDirective = SPAngularProvider({
$id: Now.ID['my-directive'],
name: 'myDirective',
type: 'directive',
script: Now.include('./directive-script.js'),
})
SPWidget({
$id: Now.ID['widget-with-provider'],
name: 'Widget with Provider',
id: 'widget-with-provider',
htmlTemplate: '<div><my-directive></my-directive></div>',
serverScript: Now.include('./server-script.js'),
angularProviders: [myDirective],
})
```