Stock Quote

Display and track stock performance in real-time.

Company Name













Data provided for free by IEX. View IEX’s Terms of Use


Quote Lookup:

What We Built

In this example, we built a widget that gets real-time stock performance data from IEX Trading*. 
*Stock data provided free of charge by IEX. Check out their Terms of Use.

How We Built It

Page Elements

We added six text elements to the mediaBox. One text element displays the current date. The remaining text elements are used as labels for the stock info: open, close, volume, low and high. Then, we added two vector art images—an up arrow and a down arrow. These arrows appear when a stock’s value goes up or down.


We added the following properties to our widget:

  • percentChangeThreshold: This numeric property is the amount of change in the stock value that will trigger the changeAlert event. 

  • refreshInterval: This numeric property represents how frequently the stock information refreshes in the widget.

  • symbol: This text property determines which stock’s data is displayed in the widget.


Users will be able to set all of these properties from their widget settings.



  • Use an HTML template for the styling of the percentageChange text. This lets us change the color of the text to green (positive) or red (negative), depending on the stock’s change value.

  • When the page loads, call refresh so that the widget gets the current stock value.

  • When widget properties change, the widget automatically calls onPropsChanged(oldProps, newProps) with refresh() to update the widget. For example, when a user changes the stock property, we refresh the widget to display the data for that stock.

  • In the refresh() function, call getStockData() to create a URL that queries the IEX API and returns the results as a JSON object.

  • Use the processQuote() function to process the data returned from the IEX API. Set the latest stock value, company name and all other labels to their matching elements in the widget. Based on a positive or negative change in the stock value, determine if the value should be shown in red with a red down arrow, or green with a green up arrow, and provide that information for the HTML template. This function also tests it the percent change in the stock value is greater than the threshold set by the user. If it is, the function fires the changeAlert event. We can use this event to perform any action we want on the site.

Code Snippet

import {fetch} from 'wix-fetch';


// When setting the percentage changed text, we'll use HTML, so that we can change the color on the fly.

// This represents the template for that HTML. %COLOR% and %CHANGE% are placeholders that will be replaced in the code below

const percentChangeHTMLTemplate = '<p class="p1">'+

'<span style="color:%COLOR%;font-family:poppins-semibold,poppins,sans-serif">%CHANGE% %</span></p>'


let refreshTimer;


// onReady is called when the widget loads

$w.onReady(function () {

   // Refresh the stock quote




/* onPropsChanged is called when the widget's properties change.

Property values can change at runtime by code written on the site, or when you preview your widget here in the App Builder. */     

$widget.onPropsChanged((oldProps, newProps) => {

   // Refresh the stock quote






@description Refreshes the stock quote


export function refresh(){

   // Call the stock API and process the results



   // If there was a previous refresh timer, clear it first



   // Set the new interval based on the timing defined in the property 'refreshInterval'

   let intervalInMilliseconds = $widget.props.refreshInterval * 1000;

   refreshTimer = setInterval(() => {

       // Call the stock API and process the results


   }, intervalInMilliseconds);



function getStockData(){

   // The widget's property 'symbol' holds the stock symbol for which we want to get the quote

   let symbol = $widget.props.symbol;


   // Build the URL for data retrieval from

   let url = '';  

   let fullUrl = url + symbol + '/batch?types=quote';


   // Make an HTTP GET call to that URL

   fetch(fullUrl, {method: 'get'})

       // When that comes back successfully, read the response as a json object

       // (for the sake of this example, we're ignoring error cases)

       .then(response => response.json())

       // When the json response is ready, keep going

       .then(json => {

// Make sure we got the expected data back (in this case, the API returns the bulk of the data in the 'quote' member of the object)

           let quote = json.quote;


               console.log('Missing quote in response from API');




           try {           

               // Try to process the quote


           } catch (err) {

               console.log('Error processing quote from API - ', err);





function processQuote(quote){

   // Process the JSON returned by the API.  See API reference here -



   // Set the latestPrice and companyName elements accordingly

   $w('#latestPrice').text = '$' + quote.latestPrice.toFixed(2);

   $w('#companyName').text = quote.companyName;


   // Get the percentage changed and put it in the HTML template we'll use to display it

   let percentChange = quote.changePercent * 100;

   let percentChangeHTML = percentChangeHTMLTemplate.replace('%CHANGE%', percentChange.toFixed(2));

   let changeColor;


   // Check if this was a positive or negative change

   if(percentChange >= 0){

       // Set the color to green and show the 'positiveChangeSVG' element which displays the green arrow

       changeColor = '#6BC76B';




   else {

       // Set the color to red and show the 'negativeChangeSVG' element which displays the red arrow

       changeColor = '#FA4B4B';




   // Use the color determined above to replace the color in the HTML snippet, then display it inthe 'percentChange' element

   percentChangeHTML = percentChangeHTML.replace('%COLOR%', changeColor);

   $w('#percentChange').html = percentChangeHTML;


   // Set all the other elements according to the different values we received

   $w('#open').text =;

   $w('#close').text = quote.close.toFixed(2);

   $w('#low').text = quote.low.toFixed(2);

   $w('#high').text = quote.high.toFixed(2);

   $w('#volume').text = quote.latestVolume.toString();

   $w('#date').text = quote.latestTime;


   // If the change is bigger than the requested trigger, fire an event

   if(Math.abs(percentChange) >= $widget.props.percentChangeThreshold){

       // $widget.fireEvent fires an event that can be handled with custom JavaScript on the site

       $widget.fireEvent('changeAlert', percentChange);

       console.log('Fired OnChangeAlert with value of ', percentChange);



Was this page helpful?

Any questions? Contact us or create a post in the App Builder Forum.

More Resources

Find all the information you need to get started on your next web component.

Learn how to get up and running with Wix App Builder fundamentals.

Learn more about the Wix App Builder and how it works.

Follow step-by-step guides to help you develop your next web component.

Take full control of your web components with Wix App Builder APIs.

Ask questions and get expert advice from Wix App Builder professionals.

Got questions? Find all your Wix App Builder answers here.