NetSuite Portlets
Portlets are dashboard widgets that display customized content, reports, and interactive elements on the NetSuite home page.
Portlet Types
| Type | Description | Use Case |
|---|---|---|
| Form Portlet | Display a form for data entry | Quick order entry, search forms |
| List Portlet | Display tabular data | Pending approvals, recent records |
| HTML Portlet | Custom HTML content | Charts, embeds, formatted content |
| Links Portlet | Grouped navigation links | Quick links, shortcuts |
Architecture
PORTLET ARCHITECTURE
─────────────────────────────────────────────────────────
┌─────────────────────────────────────────────────────────┐
│ DASHBOARD │
├───────────────────┬─────────────────┬───────────────────┤
│ LEFT COLUMN │ CENTER COLUMN │ RIGHT COLUMN │
│ │ │ │
│ ┌─────────────┐ │ ┌───────────┐ │ ┌─────────────┐ │
│ │ List │ │ │ Form │ │ │ HTML │ │
│ │ Portlet │ │ │ Portlet │ │ │ Portlet │ │
│ │ │ │ │ │ │ │ │ │
│ │ Pending │ │ │ Quick │ │ │ KPI │ │
│ │ Approvals │ │ │ Order │ │ │ Dashboard │ │
│ └─────────────┘ │ └───────────┘ │ └─────────────┘ │
│ │ │ │
│ ┌─────────────┐ │ ┌───────────┐ │ ┌─────────────┐ │
│ │ Links │ │ │ List │ │ │ Form │ │
│ │ Portlet │ │ │ Portlet │ │ │ Portlet │ │
│ └─────────────┘ │ └───────────┘ │ └─────────────┘ │
└───────────────────┴─────────────────┴───────────────────┘
Script Structure
Portlet Script Type
/**
* @NApiVersion 2.1
* @NScriptType Portlet
*/
define(['N/search', 'N/ui/serverWidget'],
(search, serverWidget) => {
/**
* Render portlet content
* @param {Object} params
* @param {serverWidget.Portlet} params.portlet - Portlet object
* @param {number} params.column - Dashboard column (1, 2, or 3)
* @param {string} params.entityid - Entity context (if any)
*/
const render = (params) => {
const portlet = params.portlet;
portlet.title = 'My Custom Portlet';
// Add content based on portlet type
// ...
};
return { render };
});
Portlet Parameters
| Parameter | Type | Description |
|---|---|---|
params.portlet | Portlet | The portlet object to populate |
params.column | number | Column position (1=left, 2=center, 3=right) |
params.entityid | string | Entity ID if on record dashboard |
Deployment
Script Record
Customization → Scripting → Scripts → New
| Field | Value |
|---|---|
| Type | Portlet |
| Script File | SuiteScripts/portlet_script.js |
Script Deployment
Customization → Scripting → Script Deployments
| Field | Description |
|---|---|
| Applied To | Entity dashboard or general |
| Status | Released |
| Role Restrictions | Who can see the portlet |
Adding to Dashboard
Home → Personalize Dashboard → Custom Portlets
Quick Examples
List Portlet
const render = (params) => {
params.portlet.title = 'Pending Approvals';
// Add columns
params.portlet.addColumn({ id: 'tranid', type: 'text', label: 'Transaction', align: 'LEFT' });
params.portlet.addColumn({ id: 'entity', type: 'text', label: 'Customer', align: 'LEFT' });
params.portlet.addColumn({ id: 'total', type: 'currency', label: 'Amount', align: 'RIGHT' });
// Add rows from search
search.create({
type: 'salesorder',
filters: [['status', 'is', 'pendingApproval']],
columns: ['tranid', 'entity', 'total']
}).run().each(result => {
params.portlet.addRow({
tranid: result.getValue('tranid'),
entity: result.getText('entity'),
total: result.getValue('total')
});
return true;
});
};
Form Portlet
const render = (params) => {
params.portlet.title = 'Quick Search';
params.portlet.addField({
id: 'custpage_search',
type: 'text',
label: 'Search Term'
});
params.portlet.addField({
id: 'custpage_type',
type: 'select',
label: 'Record Type',
source: 'customlist_record_types'
});
params.portlet.setSubmitButton({ label: 'Search' });
};
HTML Portlet
const render = (params) => {
params.portlet.title = 'KPI Summary';
params.portlet.html = `
<div style="display: flex; justify-content: space-around; padding: 20px;">
<div style="text-align: center;">
<div style="font-size: 32px; color: #27ae60; font-weight: bold;">$125K</div>
<div>Orders Today</div>
</div>
<div style="text-align: center;">
<div style="font-size: 32px; color: #3498db; font-weight: bold;">47</div>
<div>Pending Fulfillment</div>
</div>
<div style="text-align: center;">
<div style="font-size: 32px; color: #e74c3c; font-weight: bold;">12</div>
<div>Overdue Invoices</div>
</div>
</div>
`;
};
Best Practices
Performance
- Cache search results when possible
- Limit rows displayed (use pagination)
- Avoid complex calculations on render
User Experience
- Keep portlets focused on single purpose
- Use appropriate column widths
- Provide clear labels and formatting
Security
- Respect user permissions
- Filter data based on role
- Validate form submissions
Related Topics
- Script Portlets - Detailed SuiteScript examples
- List/Form Portlets - Interactive portlets
- Dashboard Best Practices - Design guidelines