DEV Community

Jason Shouldice
Jason Shouldice

Posted on • Originally published at vicistack.com

How to Reshape the VICIdial Agent Interface Without Touching Source Code

The VICIdial agent screen looks like it was designed in 2006. That's because it was. PHP-rendered HTML, inline JavaScript, no component library. It loads once when the agent logs in and never reloads during the shift -- everything after that is AJAX calls and DOM updates.

But here's what most admins miss: it's actually deeply customizable. You can relabel every field, embed external apps via IFRAME, inject CSS and JavaScript, build custom qualification forms, and configure hotkeys -- all without modifying a single line of VICIdial source code.

I've seen floors lose 10-15 minutes per agent per hour to interface friction. Fields they don't need, missing data they do need, three tabs to enter a disposition. Multiply that across 30 agents and you're burning a full-time employee's worth of labor every shift on UI overhead alone.

Understanding the Architecture

The agent screen is generated by vicidial.php in the web root. When an agent logs in, the server generates a single HTML page containing the complete interface layout, inline JavaScript for all client-side interactions, AJAX calls for real-time updates, and IFRAMEs for web forms and custom content.

The page does not reload during a shift. That means:

  • Custom CSS and JavaScript injected at load time persist for the entire session
  • DOM modifications via JavaScript work, but page reloads reset everything
  • Web forms in IFRAMEs can communicate with the parent frame via JavaScript (with same-origin caveats)

Three Layers of Customization

Layer 1 -- Admin config. Screen Labels, button visibility, layout options. No code required. Go to Admin > Screen Labels, create a new entry, rename fields. "Address 1" becomes "Service Address." "Comments" becomes "Qualification Notes." "Vendor Lead Code" becomes "Policy Number." Different campaigns get different label sets -- insurance shows "Medical History Notes" where solar shows "Roof Type."

Layer 2 -- Web forms and scripts. HTML/PHP/JS content loaded in IFRAMEs within the agent screen. VICIdial passes lead data as URL parameters using --A--field_name--B-- syntax. Your web form receives the data and renders whatever UI you want. You get up to three web forms per campaign.

Layer 3 -- JavaScript injection. Custom JS loaded via screen label headers that modifies the agent screen DOM directly. This is where you add custom tabs, restyle the interface with CSS overrides, or wire up interactions between the parent frame and your embedded content. Advanced, but powerful.

Screen Labels: The Easiest Win

Navigate to Admin > Screen Labels. Create a new entry, give it a descriptive name ("Insurance Campaign Labels"). Each label field maps to an agent screen element:

Screen Label Field Default Customization Example
agent_screen_title Agent Screen Your Company Name
first_name_label First Name Client First Name
address1_label Address 1 Property Address
phone_number_label Phone Primary Phone
alt_phone_label Alt Phone Cell Phone
email_label Email Client Email
comments_label Comments Qualification Notes
vendor_lead_code_label Vendor Lead Code Policy Number

Assign label sets under Campaign > Detail > Screen Labels dropdown. Different campaigns, different labels. Zero code.

Hiding Fields

To hide fields agents don't need, inject CSS in the label_header field:

<style>
  #address2Label, #address2Field { display: none !important; }
  #address3Label, #address3Field { display: none !important; }
  #date_of_birthLabel, #date_of_birthField { display: none !important; }
</style>
Enter fullscreen mode Exit fullscreen mode

Caveat: Element IDs vary between VICIdial SVN revisions. Use browser dev tools (F12 > Inspect Element) to find the right IDs for your version before you write the CSS.

Web Forms: Where Real Customization Happens

Web forms are VICIdial's most powerful customization tool. They load in an IFRAME within the agent screen. When a call connects, VICIdial passes lead data to the form URL as query parameters using variable substitution:

/custom/qual.html?first=--A--first_name--B--&last=--A--last_name--B--&phone=--A--phone_number--B--&lead_id=--A--lead_id--B--&user=--A--user--B--&call_id=--A--call_id--B--&city=--A--city--B--&state=--A--state--B--&zip=--A--postal_code--B--
Enter fullscreen mode Exit fullscreen mode

Available variables include first_name, last_name, phone_number, lead_id, vendor_lead_code, list_id, address1, city, state, postal_code, email, campaign, user, uniqueid, call_id, recording_filename, agent_log_id, did_id, and did_extension. Custom fields (Admin > Custom Fields) are also available using their field name.

Set Web Form Target to IFRAME (embedded in agent screen) and enable auto-open on connect. Agents see the form data immediately without clicking.

What the Form Can Do

Your web form is a full web application embedded in the agent screen. It can:

  • Display lead data in any format you design
  • Collect additional qualification data from the agent
  • Submit to your own backend (save to database, push to CRM, trigger workflows)
  • Communicate back to the parent VICIdial frame via JavaScript -- including triggering transfers with parent.document.getElementById('MainXfeRButtoN').click()

The form persists as long as the call is active. When the next call connects, VICIdial refreshes the IFRAME with new lead data.

Script Tabs

The Script tab is a built-in IFRAME designed for agent talk tracks. Admin > Scripts, create a new entry, write HTML with the same variable substitution:

"Hi, is this --A--first_name--B--? I'm reaching out because you may qualify for additional Medicare benefits in --A--state--B--..."

Scripts support full HTML/CSS. You can style them however you want, add objection-handling sections with collapse/expand, include compliance disclosures, build decision trees. Assign scripts per campaign or per inbound group for blended operations where agents handle both outbound and inbound calls.

IFRAME CRM Integration

One of VICIdial's most underused features. Set your campaign web form URL to your CRM's lead detail page:

https://your-crm.com/lead/view?id=--A--vendor_lead_code--B--&agent=--A--user--B--
Enter fullscreen mode Exit fullscreen mode

The CRM loads in the IFRAME with the correct lead. When a new call connects, VICIdial refreshes with new lead data. Single pane of glass, no window switching.

For operations where agents need the CRM visible at all times (not hidden in a tab), inject CSS via screen labels to resize the main agent container and add a persistent IFRAME panel alongside it:

<style>
  #agent_main_container { width: 60% !important; float: left; }
</style>
<iframe src="https://your-crm.com" style="width: 38%; height: 600px; position: fixed; right: 1%; top: 100px; border: 1px solid #ccc;"></iframe>
Enter fullscreen mode Exit fullscreen mode

You can also create entirely new tabs by injecting JavaScript via screen label headers that adds elements to the tab bar and creates corresponding IFRAME content panels.

Disposition Hotkeys

Map keyboard shortcuts to your most common dispositions under Campaign > Disposition Hotkeys. If agents can hit a single key instead of clicking through a dropdown, ACW drops measurably.

Most floors map keys 1-5 to their top five dispositions. Train agents on day one and enforce it. The time savings are immediate -- 3-5 seconds per disposition across hundreds of calls per agent per day adds up fast.

Custom Transfer Lists

Configure quick-transfer buttons under Campaign > XFER Group. Agents see named buttons ("Transfer to Closer," "Send to Spanish Team") instead of typing extension numbers. This eliminates misrouted transfers and shaves seconds off every warm transfer.

JavaScript Injection: Advanced Customization

The screen label header field accepts HTML, which means it accepts <script> tags. This is where advanced customization lives.

Adding Custom Tabs

<script>
document.addEventListener('DOMContentLoaded', function() {
  var tabBar = document.getElementById('agent_tab_bar');
  if (tabBar) {
    var newTab = document.createElement('span');
    newTab.innerHTML = '<a href="#" onclick="showCustomTab(); return false;" style="padding: 5px 15px; background: #eee; border: 1px solid #ccc; margin-left: 5px;">CRM</a>';
    tabBar.appendChild(newTab);
  }
});

function showCustomTab() {
  var panels = document.querySelectorAll('.tab-panel');
  panels.forEach(function(p) { p.style.display = 'none'; });
  var crmFrame = document.getElementById('custom_crm_frame');
  if (!crmFrame) {
    crmFrame = document.createElement('iframe');
    crmFrame.id = 'custom_crm_frame';
    crmFrame.src = 'https://your-crm.com';
    crmFrame.style.width = '100%';
    crmFrame.style.height = '400px';
    crmFrame.style.border = 'none';
    document.getElementById('agent_main_content').appendChild(crmFrame);
  }
  crmFrame.style.display = 'block';
}
</script>
Enter fullscreen mode Exit fullscreen mode

Auto-Formatting Phone Numbers

Inject a script that formats the phone number field as agents type:

<script>
var phoneField = document.getElementById('phone_number');
if (phoneField) {
  phoneField.addEventListener('input', function(e) {
    var x = e.target.value.replace(/\D/g, '').match(/(\d{0,3})(\d{0,3})(\d{0,4})/);
    e.target.value = !x[2] ? x[1] : '(' + x[1] + ') ' + x[2] + (x[3] ? '-' + x[3] : '');
  });
}
</script>
Enter fullscreen mode Exit fullscreen mode

Timer Displays

Add a visible call timer that's more prominent than VICIdial's default:

<div id="custom-timer" style="position: fixed; top: 10px; right: 10px; background: #222; color: #0f0; padding: 8px 15px; font-size: 24px; font-family: monospace; border-radius: 4px; z-index: 9999;">00:00</div>
<script>
var timerEl = document.getElementById('custom-timer');
var startTime = null;
setInterval(function() {
  var status = document.getElementById('AgentStatusDisplay');
  if (status && status.textContent.includes('INCALL')) {
    if (!startTime) startTime = Date.now();
    var elapsed = Math.floor((Date.now() - startTime) / 1000);
    var mins = String(Math.floor(elapsed / 60)).padStart(2, '0');
    var secs = String(elapsed % 60).padStart(2, '0');
    timerEl.textContent = mins + ':' + secs;
    timerEl.style.display = 'block';
  } else {
    startTime = null;
    timerEl.style.display = 'none';
  }
}, 1000);
</script>
Enter fullscreen mode Exit fullscreen mode

These injected scripts run once at page load and persist for the entire session.

Web Form Variable Reference

The complete list of variables available in web form and script URLs:

Variable Description
--A--first_name--B-- Lead first name
--A--last_name--B-- Lead last name
--A--phone_number--B-- Phone being dialed
--A--lead_id--B-- VICIdial lead ID
--A--vendor_lead_code--B-- Vendor lead code (your external ID)
--A--list_id--B-- List ID
--A--address1--B-- Address line 1
--A--city--B-- City
--A--state--B-- State
--A--postal_code--B-- ZIP/postal code
--A--email--B-- Email address
--A--campaign--B-- Campaign ID
--A--user--B-- Agent username
--A--uniqueid--B-- Call unique ID
--A--call_id--B-- VICIdial call ID
--A--recording_filename--B-- Recording file name
--A--agent_log_id--B-- Agent log entry ID
--A--did_id--B-- DID ID for inbound
--A--did_extension--B-- DID extension

Custom fields (Admin > Custom Fields) are also available using their field name in the same --A--fieldname--B-- syntax.

This is powerful because it means your web form receives the full lead context on every call. You can build qualification forms that pre-populate with known data, CRM lookups by vendor_lead_code, or recording retrieval interfaces that play back the call the agent is currently on.

Button Visibility and Layout Options

VICIdial has dozens of toggle settings under Campaign > Detail that control which buttons and panels agents see:

  • Show Agent Transfer -- enable/disable the transfer button panel
  • Show Agent Dial Pad -- show/hide the DTMF dial pad
  • Show Agent VM Transfer -- voicemail transfer button
  • Enable Recording -- agent-controlled call recording toggle
  • Show Park Button -- call parking
  • ViciPhone Panel Position -- where the WebRTC softphone panel appears

For new agent teams, hide everything non-essential. Start with just the dial controls, disposition dropdown, and your custom web form. Add buttons as agents get comfortable. A cluttered interface slows everyone down and increases training time.

What Breaks

The agent screen is a single long-lived page. DOM changes from injected JavaScript persist for the session but reset if the page reloads (browser refresh, session timeout, VICIdial update). Web forms in IFRAMEs from different origins can't access the parent frame's DOM -- browser same-origin policy prevents it.

VICIdial's element IDs can shift between SVN revisions. After any VICIdial update, check your CSS selectors and JavaScript hooks. What worked on build 3400 might target a different element on build 3500. Keep a test agent account specifically for verifying customizations after updates.

Custom JavaScript that hooks into VICIdial's internal functions (like intercepting the disposition handler) can break when VICIdial updates change function names or DOM structure. Stick to adding new elements and styling existing ones rather than overriding VICIdial's JavaScript functions.

Cross-origin restrictions are the most common surprise. If your web form lives on a different domain than VICIdial, the IFRAME cannot access the parent frame's DOM. The parent.document.getElementById('MainXfeRButtoN').click() trick for triggering transfers only works if both the web form and VICIdial are on the same origin. If they're on different domains, use window.postMessage() for cross-frame communication -- but note that VICIdial doesn't have a built-in message handler, so you'd need to inject a listener via JavaScript injection in the screen labels.

Performance Considerations

Web forms loaded in IFRAMEs add to the page's total resource consumption. If your web form is a heavy React application pulling data from multiple APIs, it will slow down the agent's browser. Keep web forms lightweight -- plain HTML/CSS/vanilla JS is ideal. Agent workstations are often low-spec machines; don't assume desktop-class hardware.

If you're embedding your CRM via IFRAME and the CRM loads 10 MB of JavaScript, consider building a lightweight "agent view" endpoint in your CRM specifically for the VICIdial IFRAME. Strip out navigation, dashboards, and anything the agent doesn't need on a per-call basis.

Auto-opening web forms on every call connect means the IFRAME reloads with new URL parameters on every call. If your web form makes API calls on load, that's an API call per call. At 20 calls per hour per agent across 50 agents, that's 1,000 web form loads per hour. Make sure your web form backend can handle that volume.

The interface will never be pretty. But with the right customization, it doesn't have to be slow, cluttered, or confusing. The goal isn't to make it look modern -- it's to remove friction so agents spend more time talking and less time clicking.

ViciStack configures custom agent screens for every campaign type -- insurance, solar, home services, debt. We build the web forms, set up the CRM integration, configure the hotkeys, and test across SVN versions. Agents see exactly what they need, and nothing they don't. Talk to us if your interface is costing you time.

Originally published at https://vicistack.com/blog/vicidial-agent-screen-customization/

Top comments (0)