Shutterstock UI

The Shutterstock UI search widget lets you embed Shutterstock image and video search on your site. You can customize actions to happen when users search or click items, and you can get information about what they search for and click.

Prerequisites

The widget works only with API applications that have referrer authentication enabled. In your application, you must specify the host names on which you will host the widget. You can specify localhost as a referrer for local testing.

To add referrer authentication to your app:

  1. Go to https://shutterstock.com/account/developers/apps.
  2. Create or edit an app you want to use with the widget.
  3. In the Referrer field, specify a comma-separated list of host names that you will host the widget on.
  4. Make sure that each referrer host name is also listed in the Callback URL field.
  5. Save the app and note the consumer key.

Now you can use the consumer key from your application to authenticate your instance of the widget.

Generating the widget code

You can use the wizard on this page to generate a starter widget with the settings and parameters that you choose:

https://tech.shutterstock.com/shutterstock-ui-wizard/

This page lets you edit the widget code in a live preview so you can set it up the way you want it:

Embedding the widget on a page

To add the widget to a page, import its source files and pass parameters that specify where to place it on the page.

  1. On the page, import the JavaScript and CSS files:

    <link rel="stylesheet" type="text/css" href="https://api-cdn.shutterstock.com/0.1.13/static/css/sstk-widget.css">
    <script src="https://api-cdn.shutterstock.com/0.1.13/static/js/sstk-widget.js"></script>

    In most cases, use the wizard to get links to a specific version of the CSS and JS files. If you link to these specific versions, the widget stays on that version until you choose to upgrade.

  2. Create an HTML element to contain the widget and give it an ID, such as widget-container.

  3. Create the the widget object and then call its search() method to render it when the page loads. Without search results, it does not load on the page.

    <script>
      window.onload = () => {
        const widget = new ShutterstockWidget({
          mediaType: 'images',
          container: document.getElementById('widget-container'),
          showMore: true,
          key: 'YOUR_API_APP_CONSUMER_KEY',
          showSearchBar: true
        });
    
        widget.search({});
      }
    </script>
  4. In the the widget parameters, specify your API application's consumer key and the ID of the HTML element.

  5. In the mediaType parameter, specify images or videos. The widget can show only one type of media at a time.

Now the widget appears on the page. You can implement the onError, onItemClick, and onSearch callbacks to respond to actions as described below.

The search widget looks like this with the search bar enabled:

Running the widget locally

You can try the widget locally by running it on Node.js. Because it requires referrer authentication, the widget does not work without being hosted by a server. Follow these steps to set up the widget for local testing on a simple web server:

  1. In your application, make sure that localhost is listed in both the Callback URL and Referrer fields.
  2. Install Node.js.
  3. In a command-line window, run these commands to create a folder for the widget, set up a Node.js application, and create the necessary files:
    mkdir serve-shutterstockui
    cd serve-shutterstockui
    npm init
    npm install express
    mkdir public
    touch index.js
    touch public/index.html
  4. Using any text editor, copy the following code into the index.js file:

    const express = require('express');
    const app = express();
    
    app.use(express.static('public'));
    
    app.listen(4646, () => console.log('App listening on port 4646!'));
  5. Using any text editor, copy the following code into the public/index.html file:

    <html>
      <head>
        <link rel="stylesheet" type="text/css" href="https://api-cdn.shutterstock.com/static/css/shutterstock-ui.css">
        <script src="https://api-cdn.shutterstock.com/static/js/shutterstock-ui.js"></script>
    
        <script>
          window.onload = () => {
            const widget = new ShutterstockWidget({
              mediaType: 'images',
              container: document.getElementById('widget-container'),
              key: 'YOUR_API_APP_CONSUMER_KEY',
              showSearchBar: true,
              onItemClick: (event, item) => {
                event.preventDefault();
                document.getElementById('statusText').innerHTML = `You clicked ${item.description}`;
              },
              onSearch: (search) => {
                document.getElementById('statusText').innerHTML = `Your search found ${search.total_results} results. The first result is "${search.results[0].description}"`;
              },
            });
    
            widget.search({
              query: 'thunder storm',
            });
          }
        </script>
      </head>
      <body>
        <p id="statusText"></p>
        <div id="widget-container"></div>
      </body>
    </html>
  6. Replace the variable YOUR_API_APP_CONSUMER_KEY with your consumer key.

  7. In a command-line window, run the command node index.js.
  8. In a web browser, go to the URL http://localhost:4646 to load the page.

Now you can try the widget and make changes to it locally.

Searching for media

If you set the parameter showSearchBar to true, the widget shows a search bar that users can use to search for media. No further code is required to allow simple searches. When a user types a query and clicks the search button or presses Enter, the widget uses the Shutterstock API to run the search and show the results.

To customize searches, you can use the search() method, which runs a search in the Shutterstock API and shows the results in the widget. For example, this code uses the widget to search for horizontal photos that include two people:

widget.search({
  query: document.getElementById('query').value,
  image_type: 'photo',
  orientation: 'horizontal',
  people_number: 2,
});

For image searches, you can use the following search parameters. For more information about these search parameters, see the GET /v2/images/search endpoint in the API reference. The parameters work the same way in the widget as they do when you use the API directly.

  • category: The ID or name of a Shutterstock-defined category; see GET /v2/images/categories in the API reference
  • contributor: An array of contributor names or IDs to show images from those contributors
  • contributor_country: An array of two character country codes to show images from contributors in those countries
  • image_type: An array of one or more image types, including "photo," "illustration," and "vector"
  • language: The two-character language code to interpret the query parameter in; see Localizing searches in the API reference
  • orientation: The orientation of the image, including "horizontal" and "vertical"
  • page: The page number of the results
  • people_number: An integer number of people in the image, from 0 to 4
  • per_page: The number of results to show per page
  • query: One or more search terms separated by spaces; you can use NOT to filter out images that match a term
  • sort: The sort order: "newest," "popular" (the default), "relevance", or "random"

For video searches, you can use the following search parameters. For more information about these search parameters, see the GET /v2/videos/search endpoint in the API reference.

  • aspect_ratio: The aspect ratio of the video, including "4_3," "16_9," and "nonstandard"
  • category: The ID or name of a Shutterstock-defined category; see GET /v2/videos/categories in the API reference
  • duration_from: The minimum duration of the video in seconds
  • duration_to: The maximum duration of the video in seconds
  • language: The two-character language code to interpret the query parameter in; see Localizing searches in the API reference
  • page: The page number of the results
  • per_page: The number of results to show per page
  • query: One or more search terms separated by spaces; you can use NOT to filter out videos that match a term
  • resolution: The resolution of the video, including "4k," "standard_definition," and "high_definition"
  • sort: The sort order: "newest," "popular" (the default), "relevance", or "random"

The search method also accepts the title parameter which sets the title of the widget if the dynamicTitle parameter is set to true. See Initialization parameters.

Responding to searches

When the API returns the search results, the widget shows the assets. You can trigger custom behavior with the onSearch callback function. This callback receives an object that has these fields:

  • searchTerm: The search query text
  • searchId: The ID of the API search
  • total_results: The number of results
  • results: The array of search results

    Image search results have these fields:

    • aspect: The aspect ratio of the image in decimal format
    • description: The description of the image
    • height: The height of the thumbnail in pixels
    • id: The ID of the asset; you can use this ID to get more information about the image from the API
    • link: A link to the image page on shutterstock.com
    • preview_1000: An object that contains the URL, width, and height of a preview image that is 1000 pixels on its larger dimension
    • preview_1500: An object that contains the URL, width, and height of a preview image that is 1500 pixels on its larger dimension
    • search_id: The ID of the API search
    • slug: A unique string that identifies the image
    • src: A link to a thumbnail image
    • url: A link to a thumbnail image
    • width: The width of the thumbnail in pixels

    Video search results have these fields:

    • description: The description of the video
    • id: The ID of the asset; you can use this ID to get more information about the video from the API
    • height: The height of the thumbnail in pixels
    • link: A link to the video page on shutterstock.com
    • preview: An object with links to preview videos:
      • mp4: A link to an MP4 preview video
      • webm: A link to a WebM preview video
    • search_id: The ID of the API search
    • slug: A unique string that identifies the video
    • src: A link to a thumbnail image
    • url: A link to a thumbnail image
    • width: The width of the thumbnail in pixels

This example of the onSearch callback function shows information about the results in an element on the page:

const widget = new ShutterstockWidget({
  mediaType: 'images',
  container: document.getElementById('widget-container'),
  key: 'YOUR_API_APP_CONSUMER_KEY',
  onSearch: (search) => {
    document.getElementById('statusText').innerHTML = `Your search found ${search.total_results} results. The first result is "${search.results[0].description}"`;
  },
});

Responding to clicks

By default, when a user clicks on an asset thumbnail, the web browser opens the shutterstock.com page for that asset.

To specify custom behavior when the user clicks on a thumbnail, you can use the onItemClick callback function. This function receives two parameters:

  • event: The JavaScript event object that represents the click event.
  • item: An object with information about the asset that the user clicked, with the same fields as elements in the results array in the onSearch callback function.

The callback function should start with the command event.preventDefault() to prevent the widget from sending the user to the shutterstock.com page, as in this example:

const widget = new ShutterstockWidget({
  mediaType: 'images',
  container: document.getElementById('widget-container'),
  key: 'YOUR_API_APP_CONSUMER_KEY',
  onItemClick: (event, item) => {
    event.preventDefault();
    alert(item.description);
  },
});

Initialization parameters

When you create the widget, you can pass these parameters to it:

ParameterTypeDescription
assetsPerPageNumberNumber of assets to show. Default is 26.
containerHtmlElement(Required) A JavaScript HtmlElement object to render the container in.
contributorarray[String]Show assets with the specified contributor names or IDs.
dynamicSubtitleBooleanIf true, you can use placeholders such as {{TOTAL_COUNT}} and {{SEARCH_TERM}} in the subtitle parameter and the widget replaces them with the total number of results and the search term.
dynamicTitleBooleanIf true, the widget updates its title to match either the search query or the value of the title parameter that you pass to the search() method.
emptyResultsSubtitleStringA custom subtitle to show when a search returns no results.
emptyResultsTitleStringA custom title to show when a search returns no results. You can include the {{SEARCH_TERM}} placeholder in the title and the widget replaces it with the search query.
imageTypearray[String]One or more types of image to return: photo, illustration, vector. By default, all image types are returned.
keyString(Required) Your Shutterstock public API consumer key. To get a key, create an application at https://shutterstock.com/account/developers/apps. The key must have referrer authentication enabled for the host name on which the widget is hosted.
languageCodeStringFor translation purposes, a 2-letter ISO 3166-1 alpha-2 country code such as DE or US. The default is EN. The widget uses this language code to translate the {{TOTAL_COUNT}} placeholder.
mediaTypeString(Required) The type of media to show in the widget: image or video.
onErrorFunctionA callback function to run when the API search or widget returns errors; see Handling errors.
onItemClickFunctionA callback function to run when the user clicks on an asset in the widget.
onSearchFunctionA callback function to run after the search has returned results.
showItemIdBooleanIf set to true, the widget shows the asset ID when the users hovers over an asset in the results.
showMoreButtonTextStringText for the pagination button. The default is "Show more."
showSearchBarBooleanWhether to show a search bar as part of the widget. The default is false.
subtitleStringSubtitle of the widget.
themeObjectAn object that specifies CSS classes. See Theming.
titleStringTitle of the widget

Theming

To override the CSS classes for the widget, pass an object with the new classes to the theme parameter. This object sets classes for the header, pagination buttons, search bar, error component, and the screen that shows an empty search result.

The object has these fields:

  • header: An object with classes for the header's container, subtitle, and title: container, title, and subtitle
  • emptySearchResults: An object with classes for the screen that shows when a search returns no results: container, title, and subtitle
  • pagination: An object with classes for the "Show more" button at the bottom of the results: container and showMore
  • searchBar: An object with classes for the search bar:
    • container: The class for the container <div> element for the search bar
    • formControlInput: The class for the form <input> element
    • inputGroup: The class for the input group that contains the search query field and submit button
    • searchButton: The class for the submit button
    • searchForm: The class for the <form> element
    • searchIconContainer: The class for the container for the submit button
    • searchIcon: The class for the submit button
  • error: Classes for the screen that shows when the API returns an error: container, title, and subtitle

For example:

{
  header: {
    container: 'containerCssClass',
    subtitle: 'subtitleCssClass',
    title: 'titleCssClass',
  },
  emptySearchResults: {
    container: 'containerCssClass ',
    subtitle: 'subtitleCssClass',
    title: 'titleCssClass',
  },
  pagination: {
    container: 'containerCssClass',
    showMore: 'showMoreCssClass',
  },
  searchBar: {
    container: 'themedContainer',
    formControlInput: 'themedFormControlInput',
    inputGroup: 'themedInputGroup',
    searchButton: 'themedSearchButton',
    searchForm: 'themedSearchForm',
    searchIconContainer: 'themedSearchIconContainer',
    searchIcon: 'themedSearchIcon',
  },
  error: {
    container: 'containerCssClass ',
    subtitle: 'subtitleCssClass',
    title: 'titleCssClass',
  }
}

Handling errors

To handle API errors, use the onError callback function, as in this example:

const widget = new ShutterstockWidget({
  mediaType: 'images',
  container: document.getElementById('widget-container'),
  key: 'YOUR_API_APP_CONSUMER_KEY',
  onError: (error) => {
    console.error(error.message);
    console.error(error.errors);
  },
});

The error.message field contains a textual description of the error. For example, if you pass an invalid value for a parameter, the description is "Validation failed."

The error.errors array has more specific information about the error. In the case of an invalid parameter value, the array includes an object with the error code, the passed parameter value, and a message about how the parameter did not match an expected value.