Skip to main content

NetSuite Portlets

Portlets are dashboard widgets that display customized content, reports, and interactive elements on the NetSuite home page.


Portlet Types

TypeDescriptionUse Case
Form PortletDisplay a form for data entryQuick order entry, search forms
List PortletDisplay tabular dataPending approvals, recent records
HTML PortletCustom HTML contentCharts, embeds, formatted content
Links PortletGrouped navigation linksQuick 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

ParameterTypeDescription
params.portletPortletThe portlet object to populate
params.columnnumberColumn position (1=left, 2=center, 3=right)
params.entityidstringEntity ID if on record dashboard

Deployment

Script Record

Customization → Scripting → Scripts → New

FieldValue
TypePortlet
Script FileSuiteScripts/portlet_script.js

Script Deployment

Customization → Scripting → Script Deployments

FieldDescription
Applied ToEntity dashboard or general
StatusReleased
Role RestrictionsWho 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