NAV Navigation
Examples
Landing image that shows people working with an API to create a rocket ship
Shutterstock UI

Current version: 2.0.3

This page always shows reference documentation for the most recent version of the Shutterstock UI widget. You can bookmark this page for the most recent version, but in most cases, use the drop-down list at the left-hand side of the page to select a version and to go to the documentation for that specific version of the widget.

Getting started

The Shutterstock UI widget lets you embed Shutterstock image and video search and licensing 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. You can implement the ability to license and download images and to browse previously licensed images.

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.

Authentication

The widget uses the same authentication that the API uses. In most cases, your application obtains an OAuth token from the API and uses that token to make requests on behalf of a Shutterstock account holder. For more information about authenticating to the API, see Authentication in the Shutterstock API reference.

After you have the token, you store it on the server side to avoid putting it in client-side code. Your application makes calls to the API, such as license requests, from that server-side code.

Quick start

You can use the wizard on this page to generate a starter widget in HTML or in React 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:

Wizard that generates widget code

Embedding the widget on a page

Embedding the widget on a page

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

    <script>
      window.onload = () => {
        const mySearchPage = {
          name: 'mySearchPage',
          component: ShutterstockWidget.components.SearchPage,
          props: {
            languageCode: 'en',
            mediaType: 'images',
            license: ['commercial'],
            showSearchBar: true,
            showMore: true,
            title: 'Search page',
            subtitle: 'Shutterstock UI',
            onItemClick: (event, item) => {
              event.preventDefault();
              console.log(`You clicked ${item.description}`);
            },
            onSearch: (search) => {
              console.log(`Your search found ${search.total_results} results. The first result is "${search.results[0].description}"`);
            },
          }
        };

        const widget = new ShutterstockWidget({
          container: document.getElementById('widget-container'),
          key: 'YOUR_API_APP_CONSUMER_KEY',
          customHeaders: {
            'x-shutterstock-application': 'Shutterstock UI Example App',
          },
          pages: [
            mySearchPage,
          ],
        });
        
        widget.render();
      }
    </script>
  </head>
  <body>
    <p id="statusText"></p>
    <div id="widget-container"></div>
  </body>
</html>

To add the widget to a page, import its source files and pass parameters that specify where to place it on the page and what pages to show. For an example, see the right-hand column.

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

    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.

  4. In the the widget parameters, specify your API application's consumer key and the ID of the HTML element. The widget can show only one type of media at a time.

  5. Add one or more pages. For information about the different pages that are available, see Customizing pages.

  6. Call the widget's render() method or the search page's search() method to initialize the widget.

Now the widget appears on the page. You can customize each widget page and implement callbacks to run actions when users search or click on elements on the page.

The widget looks like this with the search bar enabled:

Widget

Running the widget locally

For information on running the widget locally with Node.js, see Shutterstock UI on the Shutterstock developer portal.

Customizing pages

Adding pages

const myImageDetailsPage = {
  component: ShutterstockWidget.components.ImageDetailsPage,
  name: 'myImageDetailsPage',
  props: {
    showSearchBar: true,
  },
};

const widget = new ShutterstockWidget({
  languageCode: 'en',
  title: 'Shutterstock UI',
  container: document.getElementById('widget-container'),
  showMore: true,
  key: '<YOUR_APP_CONSUMER_KEY_HERE>',
  onItemClick: (e, item) => {
    e.preventDefault();
    widget.navigateTo('myImageDetailsPage', {
      item,
    });
  },
  pages: [
    myImageDetailsPage,
    mySearchPage, // Not shown in this example
  ]
});

The UI widget can show these pages:

Page Page type
Search page ShutterstockWidget.components.SearchPage
Collection pages ShutterstockWidget.components.ImageCollectionPage and ShutterstockWidget.components.VideoCollectionPage
Featured collection pages ShutterstockWidget.components.FeaturedImageCollectionPage and ShutterstockWidget.components.FeaturedVieoCollectionPage
Image details page ShutterstockWidget.components.ImageDetailsPage
Image licensing page ShutterstockWidget.components.ImageLicensingPage
License history page ShutterstockWidget.components.ImageLicenseHistoryPage

To show a page in the widget, create an object of the page type, specify a name in its name property, and add it to the widget's pages array, as in the example in the right-hand pane. You can theme and translate each page as described in Theming pages and Translating pages.

Routing users to a page

Routing users to a page

onItemClick: (e, item) => {
  e.preventDefault();
  widget.navigateTo('myImageDetailsPage', {
    item,
  });
}

To send users to a page, use the function widget.navigateTo() and pass the name property of the page object. You can call this function as part of any callback or anywhere else in your code.

The widget.navigateTo() function accepts a props parameter that overrides the properties of the target page. For example, the handler function in the right-hand pane runs when a user clicks an image. This function receives information about the image that the user clicked in the item parameter. The function passes that information in the widget.navigateTo() function, which sends the user to the image details page and overrides that page's props.item property.

Search page

Example search page

const mySearchPage = {
  name: 'mySearchPage',
  component: ShutterstockWidget.components.SearchPage,
  props: {
    mediaType: 'images',
    onItemClick: (e, item) => {
      e.preventDefault();
      widget.navigateTo('myImageDetailsPage', {
        item,
      });
    },
    assetsPerPage: 4,
    editorialCountry: "USA",
    showMore: true,
    showSearchBar: true,
    subtitle: 'Search page',
    title: 'Shutterstock UI',
  }
};


const widget = new ShutterstockWidget({
  languageCode: 'en',
  container: document.getElementById('widget-container'),
  key: 'YOUR_API_APP_CONSUMER_KEY',
  pages: [
    mySearchPage,
    myImageDetailsPage, // Not shown in this example
  ],
});

widget.render();

The asset search page is the landing page for the widget. Its properties include options such as what type of media to search for and default filters.

To set up a search page, create an object of the type ShutterstockWidget.components.SearchPage and specify the properties for the page. The example in the right-hand pane creates a simple image search page. For a complete list of properties for this page, see the ShutterstockWidget.components.SearchPage page component.

For more information about setting up the search page and responding to user activity, see Searching.

Example search page

When the user searches for media, the widget stores the search results temporarily and makes those results available to other pages. When you send the user to a page and pass the asset ID, as in the command widget.navigateTo(), the new page automatically retrieves information about the asset from those search results.

To filter or manipulate the search results, you can access the result data in the onSearch callback's response.results parameter. Then you can override the results that a page has access to by sending it to the page's props.searchResults parameter.

Collection pages

Example image collection page

const mockImageCollection = {
  "data": [
    {
      "id": "1864631416",
      "added_time": "2018-10-12T09:46:26-04:00"
    },
    {
      "id": "1670341648",
      "added_time": "2018-10-12T09:46:26-04:00"
    },
    {
      "id": "1873346401",
      "added_time": "2017-08-07T16:40:09-04:00"
    }
  ]
};

const myImageCollectionsPage = {
  name: 'myImageCollectionsPage',
  component: ShutterstockWidget.components.ImageCollectionPage,
  props: {
    items: [],
    pageTitle: 'My Image Collection',
    onItemClick: (e, item) => {
      e.preventDefault();
      console.log(
        item
      );
    },
  },
};

window.onload = () => {
  const attachClickEventListeners = () => {
    // Attach click event listener
    document.getElementById('image-collection-page-link').addEventListener('click', async () => {
      // Fetch collection contents from backend
      const imageCollection = mockImageCollection || await fetch('YOUR_BACKEND_ROUTE_TO_FETCH_COLLECTION_CONTENTS');

      widget.navigateTo('myImageCollectionsPage', {
        items: imageCollection,
      });
    });
  };

  attachClickEventListeners();

  const widget = new ShutterstockWidget({
    languageCode: 'en',
    title: 'Shutterstock UI',
    container: document.getElementById('widget-container'),
    showMore: true,
    key: '<YOUR_APP_CONSUMER_KEY_HERE>',
    customHeaders: {
      'x-shutterstock-application': 'Widget Example App',
    },
    pages: [
      myImageCollectionsPage,
    ],
  });

  widget.render();

}

The collection pages are intended to show the contents of an image or video collection. These pages do not automatically retrieve the collection contents; you must create server-side code that retrieves the contents.

Follow these general steps to set up a collection page:

  1. Create an object of the type ShutterstockWidget.components.ImageCollectionPage or ShutterstockWidget.components.VideoCollectionPage and specify the properties for the page.
  2. Set up routing to send the user to the page. For example, you can add a link on your home page or use an event handler.
  3. As part of the routing, call your server-side code that gets the collection contents via the Shutterstock API's GET /v2/images/collections/{id}/items or GET /v2/videos/collections/{id}/items endpoint.
  4. Pass the IDs of the assets in the collection to the page as an array of strings. You can pass the response from the GET /v2/images/collections/{id}/items or GET /v2/videos/collections/{id}/items endpoint to the collection page's props.items parameter.

Example featured image collection page

const myFeaturedImageCollectionPage = {
  name: 'myFeaturedImageCollectionPage',
  component: ShutterstockWidget.components.FeaturedImageCollectionPage,
  props: {
    perPage: 20,
    pageSubtitle: 'My Featured Image Collection',
    onItemClick: (e, item) => {
      e.preventDefault();
      console.log(
        item
      );
    },
  },
};

window.onload = () => {
  const attachClickEventListeners = () => {
    // Attach click event listener
    document
      .getElementById('featured-image-collection-page-link')
      .addEventListener('click', async () => {
        widget.navigateTo('myFeaturedImageCollectionPage', {
          collectionId: 19790,
        });
    });
  };

  attachClickEventListeners();

  const widget = new ShutterstockWidget({
    languageCode: 'en',
    title: 'Shutterstock UI',
    container: document.getElementById('widget-container'),
    key: '<YOUR_APP_CONSUMER_KEY_HERE>',
    customHeaders: {
      'x-shutterstock-application': 'Widget Example App',
    },
    pages: [
      myFeaturedImageCollectionPage,
    ],
  });

  widget.render();

}

The featured collection pages are intended to show the contents of a featured image or video collection. If you omit the props.pageTitle parameter, the page uses the title of the collection for the page title.

Follow these general steps to set up a featured collection page:

  1. Create an object of the type ShutterstockWidget.components.FeaturedImageCollectionPage or ShutterstockWidget.components.FeaturedVideoCollectionPage and specify the properties for the page.
  2. Set up routing to send the user to the page. For example, you can add a link on your home page or use an event handler.
  3. Pass the ID of the featured collection to the page as an integer.

Image details page

Example image details page

const myImageDetailsPage = {
  component: ShutterstockWidget.components.ImageDetailsPage,
  name: 'myImageDetailsPage',
  props: {
    showSearchBar: true,
    buttons: [
      {
        label: 'Insert preview',
        icon: '/download-comp.svg',
        onClick: (e, item) => {
          e.preventDefault();
          console.log(`Insert code to preview image ${item.id} here.`);
        },
      },
      {
        label: 'License',
        icon: '/shopping-cart.svg',
        onClick: (e, item) => {
          e.preventDefault();
          widget.navigateTo('myImageLicensingPage', {
            item,
            subscriptions, // Not shown in this example
          });
        },
      },
    ],
    subtitle: 'Details page',
    title: 'Shutterstock UI',
  },
};

const widget = new ShutterstockWidget({
  languageCode: 'en',
  title: 'Shutterstock UI',
  container: document.getElementById('widget-container'),
  key: '<YOUR_APP_CONSUMER_KEY_HERE>',
  pages: [
    mySearchPage, // Not shown in this example
    myImageLicensingPage, // Not shown in this example
    myImageDetailsPage,
  ],
});

widget.render();

To set up the page that shows details about a selected image, create an object of the type ShutterstockWidget.components.ImageDetailsPage and specify the properties for the page. The example in the right-hand pane creates a page that shows details about an image along with a button that you can implement to run an action.

You can set the asset that the page shows information about by putting that asset's information in the page's props.item parameter.

For a complete list of properties for this page, see the ShutterstockWidget.components.ImageDetailsPage page component.

Example image details page

Image licensing page

Example image licensing page

const myImageLicensingPage = {
  name: 'myImageLicensingPage',
  component: ShutterstockWidget.components.ImageLicensingPage,
  props: {
    subscriptions: [],
    buttons: [
      {
        label: 'License',
        icon: '/shopping-cart.svg',
        isPrimary: true,
        onClick: async (e, item, props) => {
          e.preventDefault();
          await fetch('Your backend route to license images');
        },
      },
    ],
    subtitle: 'Licensing page',
    title: 'Shutterstock UI',
  },
};

const overlayActions = [
  {
    label: 'License',
    icon: '/shopping-cart.svg',
    onClick: async (e, item) => {
      e.preventDefault();
      // Fetch user subscriptions
      const subscriptions = await fetch('YOUR_BACKEND_ROUTE_TO_FETCH_SUBSCRIPTIONS');
      widget.navigateTo('myImageLicensingPage', {
        subscriptions,
        item,
      });
    },
  },
];

const mockSubscriptions = [{
  id: 's87654321',
  license: 'premier',
  description: 'Premier Account',
  price_per_download: {
    local_amount: 26,
    local_currency: 'USD'
  },
  formats: [
    {
      size: 'medium',
      details_for_image: {
        width: 1000,
        height: 562,
        dpi: 300,
      },
    },
    {
      size: 'vector',
      format: 'eps',
      media_type: 'image',
      description: 'Vector'
    },
  ],
}];

const mySearchPage = {
  name: 'mySearchPage',
  component: ShutterstockWidget.components.SearchPage,
  props: {
    mediaType: 'images',
    onItemClick: (e, item) => {
      e.preventDefault();
      widget.navigateTo('myImageLicensingPage', {
        subscriptions: mockSubscriptions,
        item,
      });
    },
    overlayActions,
    assetsPerPage: 4,
    showMore: true,
    showSearchBar: true,
    subtitle: 'Search page',
    title: 'Shutterstock UI',
  }
};

const widget = new ShutterstockWidget({
  languageCode: 'en',
  title: 'Shutterstock UI',
  container: document.getElementById('widget-container'),
  showMore: true,
  key: '<YOUR_APP_CONSUMER_KEY_HERE>',
  pages: [
    myImageLicensingPage,
    mySearchPage,
  ],
});

widget.render();

The image licensing page shows the user an image and the options for licensing it, including the available image sizes and the user's active subscriptions. To set up this page, create an object of the type ShutterstockWidget.components.ImageLicensingPage and specify the properties for the page.

For an example of this page and information about licensing images with the widget, see Licensing images.

Example image licensing page

License history page

Example license history page

const mockLicenseHistory = {
  total_count: 3,
  page: 1,
  per_page: 2,
  data: [
    {
      id: "2e2342w23r23r",
      user: {
        "username": "ASDFGHJ",
      },
      "license": "premier_digital",
      "download_time": "2020-11-03T14:49:43.000Z",
      "is_downloadable": true,
      "image": {
        id: "1708754152",
        "thumb": "https://image.shutterstock.com/image-vector/cute-cats-vector-illustration-black-450w-1708754152.jpg",
        "format": {
          "size": "vector",
        },
      },
      "subscription_id": "s123456789",
      "metadata": {
        "purchase_order": "QW-123",
        "job": "",
        "client": "",
        "other": "",
      },
    },
    {
      id: "234234wsdsadasdqr23re",
      user: {
        "username": "ASDFGHJ"
      },
      "license": "premier_digital",
      "download_time": "2020-11-03T14:49:43.000Z",
      "is_downloadable": true,
      "image": {
        id: "345821210",
        "format": {
          "size": "huge",
        },
      },
      "subscription_id": "s1234567789",
      "metadata": {
        "purchase_order": "QW-123",
        "job": "",
        "client": "",
        "other": "",
      },
    },
  ],
};

const mockNextPageLicenseHistory = {
  "total_count": 3,
  "page": 2,
  "per_page": 20,
  "data": [
    {
      id: "asdasdasdasdsadsa",
      user: {
        "username": "ABCD"
      },
      "license": "standard",
      "description": "Standard",
      "download_time": "2018-05-23T14:41:53.000Z",
      "is_downloadable": false,
      "image": {
        id: "409679020",
        "format": {
          "size": "huge"
        }
      },
      "subscription_id": "s6719023902",
      "metadata": {
        "purchase_order": "-",
        "other": "-"
      }
    },
    ],
  };

window.onload = () => {
  const attachClickEventListeners = () => {
    // Attach click event listener on Home
    document.getElementById('home').addEventListener('click', () => {
      widget.navigateTo('mySearchPage');
    });

    // Attach click event listener on Downloads
    document.getElementById('license-history-page-link').addEventListener('click', async () => {
      // Fetch license history from backend.
      const licenseHistory = mockLicenseHistory || await fetch('YOUR_BACKEND_ROUTE_TO_FETCH_LICENSE_HISTORY');

      widget.navigateTo('myImageLicenseHistoryPage', {
        licenseHistory: licenseHistory,
      });
    });
  };

  attachClickEventListeners();

  const myImageLicenseHistoryPage  = {
    name: 'myImageLicenseHistoryPage',
    component: ShutterstockWidget.components.ImageLicenseHistoryPage,
    props: {
      onLicenseHistoryItemClick: (item) => {
        // Navigate to the image details page (not included in this example)
        e.preventDefault();
        widget.navigateTo('myImageDetailsPage', {
          item,
        });
      },
      getMoreResults: async (page) => {
        // Fetch more results from the server-side code
        const nextResults = mockNextPageLicenseHistory || await getLicenseHistory('Your backend route to fetch more license history results');
        return nextResults;
      },
      licenseHistory: {},
    }
  };

  const widget = new ShutterstockWidget({
    languageCode: 'en',
    title: 'Shutterstock UI',
    container: document.getElementById('widget-container'),
    showMore: true,
    key: '<YOUR_APP_CONSUMER_KEY_HERE>',
    customHeaders: {
      'x-shutterstock-application': 'Widget Example App',
    },
    pages: [
      myImageLicenseHistoryPage,
      myImageDetailsPage, //Not included in this example
    ],
  });

  widget.render();

}

The license history page is intended to show the images that the current user has licensed. This page does not automatically retrieve the images in the user's license history; you must create server-side code that retrieves that history.

Follow these general steps to set up the license history page:

  1. Create an object of the type ShutterstockWidget.components.ImageLicenseHistoryPage and specify the properties for the page, including the props.onLicenseHistoryItemClick and props.getMoreResults callbacks that respond to user actions on the page.
  2. Set up routing to send the user to the license history page. For example, you can add a link on your home page or use an event handler.
  3. As part of the routing, call your server-side code that gets the user's license history via the Shutterstock API's GET /v2/images/licenses endpoint.
  4. Pass the license history to the page. You can pass the response from the GET /v2/images/licenses endpoint to the license history page's props.licenseHistory parameter.

Theming pages

Assigning custom classes

{
  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',
  },
}

To override the CSS classes for the widget, pass an object with the new classes to the page object's theme parameter. This object sets classes for elements on the page, such as the header, pagination buttons, and search bar.

Each page has different classes that you can set. To see the classes for each page, see the theme parameter for the specific page.

The right-hand column shows an example of custom classes for the main search page.

Translating pages

The languageCode parameter sets the language for the widget. The widget provides translated UI text in these languages:

Searching

Users can search for media on the widget's search page. The widget uses the Shutterstock API to return results, so the results in the widget may not be the same as the results for the same search on shutterstock.com.

Searching for media

Searching for media

widget.getPage('mySearchPage').search({
  query: document.getElementById('query').value,
  image_type: 'photo',
  orientation: 'horizontal',
  people_number: 2,
  license: ['commercial', 'editorial'],
});

If you set the parameter showSearchBar to true, the search page 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 page's search() method, which runs a search in the Shutterstock API and shows the results in the widget. The example in the right-hand column uses the widget to search for horizontal photos of two people.

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.

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.

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

Searching for editorial media

Limiting the search to editorial media

const mySearchPage = {
  name: 'mySearchPage',
  component: ShutterstockWidget.components.SearchPage,
  props: {
    mediaType: 'editorial',
    editorialCountry: 'USA',
    assetsPerPage: 4,
    showMore: true,
    showSearchBar: true,
    subtitle: 'Editorial search page',
    title: 'Shutterstock UI',
  }
};

To limit the search to editorial media, ensure that you are using a consumer key that is enabled for editorial media. Then, set these parameters on the search page, as in the example in the right-hand pane:

Now the widget shows only editorial media in the search results and you can license and download the media as usual.

Adding filters for editorial or non-editorial media

const searchFilters =  {
  showFilterDrawer: true,
  searchBarDropdownFilters: [
    {
      label: 'Images',
      assetType: 'images',
    },
    {
      label: 'Footage',
      assetType: 'videos',
    },
    {
      label: 'Editorial',
      assetType: 'editorial',
    },
  ],
};

const mySearchPage = {
  name: 'mySearchPage',
  component: ShutterstockWidget.components.SearchPage,
  props: {
    mediaType: 'images',
    editorialCountry: 'USA',
    searchFilters,
    assetsPerPage: 4,
    showMore: true,
    showSearchBar: true,
    subtitle: 'Search page',
    title: 'Shutterstock UI',
  }
};

To allow the user to switch between editorial and non-editorial media, set the mediaType parameter to "images" or "videos" and set the editorialCountry parameter as usual. Then, add custom search filters for editorial and non-editorial media, as in the example in the right-hand pane.

For more information about accessing editorial media, see the API reference.

Getting search suggestions

Getting image suggestions based on text

{
  searchSuggestions: {
    numberOfSuggestionRows: 3,
    enable: true,
    textProvider: () => {
      // Text to use to provide recommendations
      return "Planting flowers is a great way to make springtime more beautiful.";
    },
  },
};

The widget can provide suggestions based on English text that you provide through a function. The function can return complete sentences or individual keywords up to 100,000 characters. See the example in the right-hand pane.

To set up search suggestions, add the searchSuggestions object to the widget. This object has these fields:

When you provide text for search suggestions, the widget adds a "View recommendations" button above the usual search results. Users can click this button to see the suggestion results.

Responding to searches

Responding to search results

const mySearchPage = {
  name: 'mySearchPage',
  component: ShutterstockWidget.components.SearchPage,
  props: {
    mediaType: 'images',
    editorialCountry: "USA",
    onSearch,
    subtitle: 'Search page',
    title: 'Shutterstock UI',
  }
};

function onSearch({ searchTerm, searchId, total_results, results }) {
  console.log(`Your search for ${searchTerm} found ${total_results} results. The first result is "${results[0].description}"`);
}

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

The example in the right-hand column uses the onSearch callback to log information about the results in the browser console.

Responding to clicks

Responding to click events

const mySearchPage = {
  name: 'mySearchPage',
  component: ShutterstockWidget.components.SearchPage,
  props: {
    mediaType: 'images',
    onItemClick,
    subtitle: 'Search page',
    title: 'Shutterstock UI',
  }
};

function onItemClick(e, item) {
  e.preventDefault();
  console.log(item.description);
}

By default, when a user clicks on an asset thumbnail on the search page, 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. This function receives two parameters:

The callback should start with the command event.preventDefault() to prevent the widget from sending the user to the shutterstock.com page, as in the example in the right-hand pane.

Adding overlay actions

Adding overlay actions to results

const overlayActions = [
  {
    label: 'Insert preview',
    icon: '/download-comp.svg',
    onClick: (e, item) => {
      e.preventDefault();
      console.log(`Inserting preview image:${item.id}`);
    }
  },
  {
    label: 'License',
    icon: '/shopping-cart.svg',
    onClick: (e, item) => {
      e.preventDefault();
      widget.navigateTo('myImageLicensingPage', {
        item,
      });
    }
  },
];

const mySearchPage = {
  name: 'mySearchPage',
  component: ShutterstockWidget.components.SearchPage,
  props: {
    mediaType: 'images',
    overlayActions,
    subtitle: 'Search page',
    title: 'Shutterstock UI',
  }
};

You can also add clickable icons to the search results and run actions when the user clicks them, such as showing information about the piece of media or going to a page to license and download it. These clickable icons have an onClick callback that works just like the onItemClick callback.

Set these actions in the widget's overlayActions array, as in the example in the right-hand pane. This example adds an action that logs the image ID to the browser console and another that goes to a licensing page for the asset.

Two overlay actions on an image

Handling errors

Handling errors

const mySearchPage = {
  name: 'mySearchPage',
  component: ShutterstockWidget.components.SearchPage,
  props: {
    mediaType: 'images',
    onError,
    subtitle: 'Search page',
    title: 'Shutterstock UI',
  }
};

function onError(error) {
  console.error(error.message);
  console.error(error.errors);
}

To handle search errors, use the onError callback on the search page.

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.

Licensing images

To license images, you add pages that guide the user through the process of viewing an image, selecting the appropriate subscription and size, and confirming the licensing transaction. To avoid putting your Shutterstock API credentials in client-side code, you must set up server-side code to get subscription info and complete the license and download process.

To set up the licensing and downloading process on the widget, follow these general steps:

  1. Create an image details page, which is an object of the type ShutterstockWidget.components.ImageDetailsPage.
  2. On the image details page, using the props.button parameter, create a button that sends the user to the image licensing page. See Setting up the image details page.
  3. On the server side, using the Shutterstock API, retrieve information about the user's subscriptions.
  4. Pass the information about the image and information about the user's subscriptions to the image licensing page.
  5. Create an image licensing page, which is an object of the type ShutterstockWidget.components.ImageLicensingPage. See Setting up the image licensing page.
  6. Add one or more buttons to the page and add callback functions to the buttons. These callbacks can do whatever you need to do, but in most cases, use the callbacks to call server-side code that uses the Shutterstock API to license the image or run some other task.
  7. On the server side or the client side, download the image or handle the image file in some other way.

Setting up the image details page

Image details page that passes information to the image licensing page

const myImageDetailsPage = {
  component: ShutterstockWidget.components.ImageDetailsPage,
  name: 'myImageDetailsPage',
  props: {
    buttons: [
      {
        label: 'License',
        icon: '/shopping-cart.svg',
        isPrimary: true,
        onClick: async (e, item) => {
          e.preventDefault();
          // Fetch user subscriptions
          const subscriptions = await fetch('YOUR_BACKEND_ROUTE_TO_FETCH_SUBSCRIPTIONS');
          widget.navigateTo('myImageLicensingPage', {
            subscriptions,
            item,
          });
        },
      },
    ],
  },
};

A straightforward way to move the user to a licensing page is to start from the image details page. The example in the right-hand column includes a button that sends the user to the image licensing page.

To get the correct data to the image licensing page, the onClick handler for the button must retrieve the user's subscriptions from the GET /v2/user/subscriptions endpoint in the Shutterstock API. You must configure server-side or backend code to retrieve this subscription information.

The onClick handler also receives an item object with information about the image that the user clicked. You can pass this object along with the response from the GET /v2/user/subscriptions endpoint to the image licensing page. These parameters become the image licensing page's props.subscriptions and props.item properties.

Showing the available image sizes

{
  "medium_jpg": {
    "display_name": "Med",
    "dpi": 300,
    "file_size": 662723,
    "format": "jpg",
    "height": 563,
    "is_licensable": true,
    "width": 1000
  },
  "small_jpg": {
    "display_name": "Small",
    "dpi": 300,
    "file_size": 178812,
    "format": "jpg",
    "height": 282,
    "is_licensable": true,
    "width": 500
  }
}

By default, the subscription information does not include the dimensions of each size of image. To show the size and DPI of each size of image, you must retrieve information about the available sizes and add that information to the subscription information. The Shutterstock API endpoint GET /v2/images/{id} provides the sizes that are available for a image.

To set the dimensions for an image, first retrieve the subscription information as usual. Then, get information about the image from the GET /v2/images/{id} endpoint and add it to the subscription data in the format.details_for_image field.

For example, the GET /v2/images/{id} endpoint might show that an image is available in two sizes and provide the dimensions for each size, as in the example in the right-hand pane.

[
  {
  "id": "s87654321",
  "license": "premier",
  "description": "Premier Account",
  "price_per_download": {
    "local_amount": 26,
    "local_currency": "USD"
  },
  "formats": [
    {
      "media_type": "image",
      "description": "Small",
      "format": "jpg",
      "min_resolution": 500,
      "size": "small",
      "details_for_image": {
        "width": 1000,
        "height": 562,
        "dpi": 300
      }
    },
    {
      "media_type": "image",
      "description": "Med",
      "format": "jpg",
      "min_resolution": 1000,
      "size": "medium",
      "details_for_image": {
        "dpi": 300,
        "height": 563,
        "width": 1000
      }
    }
    ]
  }
];

The medium_jpg and small_jpg sizes in this response correspond to the medium and small formats in the subscription information. The merged subscription information is shown in the next example in the right-hand pane.

Now when a user goes to the image licensing page, the page shows the dimensions for each size:

Selecting a size for the image

Setting up the image licensing page

Image licensing page that allows the user to select a subscription and image size and request a license for the image

const myImageLicensingPage = {
  name: 'myImageLicensingPage',
  component: ShutterstockWidget.components.ImageLicensingPage,
  props: {
    showSearchBar: true,
    subscriptions: [],
    buttons: [
      {
        label: 'License',
        icon: '/shopping-cart.svg',
        isPrimary: true,
        onClick: (e, item, props) => {
          e.preventDefault();
          await fetch('Your backend route to license images');
        }
      },
    ],
  }
};

If you pass subscription and image information as described in Setting up the image details page, the image licensing page automatically shows the subscriptions and image sizes. You must add the button that the user clicks to license the image.

In the onClick handler for the button, you must call server-side or backend code to call the Shutterstock API's POST /v2/images/licenses endpoint. It is up to you to implement this code and what the widget does after the licensing request. You might configure the widget to show the download link or add the new image to the page.

ShutterstockWidget

The Shutterstock UI widget lets you embed Shutterstock asset search on your site and license and use assets directly from the page. You can customize actions to happen when users search or click items, and you can get information about what they search for and click. You can also add pages that let users view, license, and download assets.

new ShutterstockWidget(options)

Example: Creating a search widget

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

    <script>
      window.onload = () => {
        const mySearchPage = {
          name: 'mySearchPage',
          component: ShutterstockWidget.components.SearchPage,
          props: {
            languageCode: 'en',
            mediaType: 'images',
            license: ['commercial'],
            showSearchBar: true,
            showMore: true,
            title: 'Search page',
            subtitle: 'Shutterstock UI',
            onItemClick: (event, item) => {
              event.preventDefault();
              console.log(`You clicked ${item.description}`);
            },
            onSearch: (search) => {
              console.log(`Your search found ${search.total_results} results. The first result is "${search.results[0].description}"`);
            },
          }
        };

        const widget = new ShutterstockWidget({
          container: document.getElementById('widget-container'),
          key: 'YOUR_API_APP_CONSUMER_KEY',
          customHeaders: {
            'x-shutterstock-application': 'Shutterstock UI Example App',
          },
          pages: [
            mySearchPage,
          ],
        });
        
        widget.render();
      }
    </script>
  </head>
  <body>
    <p id="statusText"></p>
    <div id="widget-container"></div>
  </body>
</html>

Create a widget with the specified options.

Param Type Description
options Object An object with the options for the widget
options.container HtmlElement (required) A valid HtmlElement to render the widget in
options.customHeaders Object Custom headers to include with requests to the Shutterstock API, in key-value pairs
options.customTranslations Object Can be used to supply additional translations; see the Translations section
options.key String (required) Your Shutterstock public API consumer key
options.languageCode String 2-letter ISO 3166-1 alpha-2 country code such as DE or US (the default); the widget uses this country code to translate the total count of results
options.pages [Page] A configuration object that includes the pages (routes) that are available in the widget

shutterstockWidget.render()

This function renders the widget in the HTML element specified by the options.container property.

shutterstockWidget.getPage(name)

Example

widget.getPage('mySearchPage').search({
  query: "river",
  image_type: 'photo',
  orientation: 'horizontal',
  license: ['commercial'],
});

This function retrieves a page object by the page name.

Param Type Description
name String The name property of the target page

shutterstockWidget.navigateTo(pageName, props)

Example

const mySearchPage = {
  name: 'mySearchPage',
  component: ShutterstockWidget.components.SearchPage,
  props: {
    mediaType: 'images',
    onItemClick: (e, item) => {
      e.preventDefault();
      widget.navigateTo('myImageDetailsPage', {
        item,
      });
    },
    editorialCountry: "USA",
    subtitle: 'Search page',
    title: 'Shutterstock UI',
  }
};

const widget = new ShutterstockWidget({
  container: document.getElementById('widget-container'),
  key: 'YOUR_API_APP_CONSUMER_KEY',
  pages: [
    myImageDetailsPage, // Not shown in this example
    mySearchPage,
  ],
});

widget.render();

This function is used to navigate between different pages of the widget.

Param Type Description
pageName String The page name
props Object An object with properties for the page

Pages

These components represent pages that you can add to the widget. To add a page, create an instance of the appropriate page component and add the instance to the widget's pages array.

FeaturedImageCollectionPage

Example

const myFeaturedImageCollectionPage = {
  name: 'myFeaturedImageCollectionPage',
  component: ShutterstockWidget.components.FeaturedImageCollectionPage,
  props: {
    perPage: 20,
    pageSubtitle: 'My Featured Image Collection',
    onItemClick: (e, item) => {
      e.preventDefault();
      console.log(
        item
      );
    },
  },
};

window.onload = () => {
  const attachClickEventListeners = () => {
    // Attach click event listener
    document
      .getElementById('featured-image-collection-page-link')
      .addEventListener('click', async () => {
        widget.navigateTo('myFeaturedImageCollectionPage', {
          collectionId: 19790,
        });
    });
  };

  attachClickEventListeners();

  const widget = new ShutterstockWidget({
    languageCode: 'en',
    title: 'Shutterstock UI',
    container: document.getElementById('widget-container'),
    key: '<YOUR_APP_CONSUMER_KEY_HERE>',
    customHeaders: {
      'x-shutterstock-application': 'Widget Example App',
    },
    pages: [
      myFeaturedImageCollectionPage,
    ],
  });

  widget.render();

}

A page that shows a featured image collection

ParameterTypeDescription
component String (Required) Set to ShutterstockWidget.components.FeaturedImageCollectionPage
name String (Required) A unique name for the page
props Object The configuration properties for the page
props.collectionId Integer (Required) The ID of the featured collection to display
props.onItemClick onItemClick A callback to run when the user clicks on an asset
props.overlayActions [OverlayAction] The overlay actions for each item
props.page Integer The page to display, defaults to 1
props.pageSubtitle String The subtitle for the page
props.pageTitle String The title for the page, defaults to the title of the featured collection
props.perPage Integer The number of images to display per page, defaults to 20
props.showItemId Boolean Whether to show the asset ID when the user hovers the mouse over an asset
props.showMore Boolean Whether to show the "Show More" button when there are more results to paginate through
props.showTitle Boolean Whether to show the page title, defaults to true
props.theme CollectionPageTheme The CSS classes for the page

FeaturedVideoCollectionPage

Example

const myFeaturedVideoCollectionPage = {
  name: 'myFeaturedVideoCollectionPage',
  component: ShutterstockWidget.components.FeaturedVideoCollectionPage,
  props: {
    perPage: 20,
    pageSubtitle: 'My Featured Video Collection',
    onItemClick: (e, item) => {
      e.preventDefault();
      console.log(
        item
      );
    },
  },
};

window.onload = () => {
  const attachClickEventListeners = () => {
    // Attach click event listener
    document
      .getElementById('featured-video-collection-page-link')
      .addEventListener('click', async () => {
        widget.navigateTo('myFeaturedVideoCollectionPage', {
          collectionId: 18509,
        });
    });
  };

  attachClickEventListeners();

  const widget = new ShutterstockWidget({
    languageCode: 'en',
    title: 'Shutterstock UI',
    container: document.getElementById('widget-container'),
    key: '<YOUR_APP_CONSUMER_KEY_HERE>',
    customHeaders: {
      'x-shutterstock-application': 'Widget Example App',
    },
    pages: [
      myFeaturedVideoCollectionPage,
    ],
  });

  widget.render();

}

A page that shows a featured video collection

ParameterTypeDescription
component String (Required) Set to ShutterstockWidget.components.FeaturedVideoCollectionPage
name String (Required) A unique name for the page
props Object The configuration properties for the page
props.collectionId Integer (Required) The ID of the featured collection to display
props.onItemClick onItemClick A callback to run when the user clicks on an asset
props.overlayActions [OverlayAction] The overlay actions for each item
props.page Integer The page to display, defaults to 1
props.pageSubtitle String The subtitle for the page
props.pageTitle String The title for the page, defaults to the title of the featured collection
props.perPage Integer The number of videos to display per page, defaults to 20
props.showItemId Boolean Whether to show the asset ID when the user hovers the mouse over an asset
props.showMore Boolean Whether to show the "Show More" button when there are more results to paginate through
props.showTitle Boolean Whether to show the page title, defaults to true
props.theme CollectionPageTheme The CSS classes for the page

ImageCollectionPage

Example

const mockImageCollection = {
  "data": [
    {
      "id": "1864631416",
      "added_time": "2018-10-12T09:46:26-04:00"
    },
    {
      "id": "1670341648",
      "added_time": "2018-10-12T09:46:26-04:00"
    },
    {
      "id": "1873346401",
      "added_time": "2017-08-07T16:40:09-04:00"
    }
  ]
};

const myImageCollectionsPage = {
  name: 'myImageCollectionsPage',
  component: ShutterstockWidget.components.ImageCollectionPage,
  props: {
    items: [],
    pageTitle: 'My Image Collection',
    onItemClick: (e, item) => {
      e.preventDefault();
      console.log(
        item
      );
    },
  },
};

window.onload = () => {
  const attachClickEventListeners = () => {
    // Attach click event listener
    document.getElementById('image-collection-page-link').addEventListener('click', async () => {
      // Fetch collection contents from backend
      const imageCollection = mockImageCollection || await fetch('YOUR_BACKEND_ROUTE_TO_FETCH_COLLECTION_CONTENTS');

      widget.navigateTo('myImageCollectionsPage', {
        items: imageCollection,
      });
    });
  };

  attachClickEventListeners();

  const widget = new ShutterstockWidget({
    languageCode: 'en',
    title: 'Shutterstock UI',
    container: document.getElementById('widget-container'),
    showMore: true,
    key: '<YOUR_APP_CONSUMER_KEY_HERE>',
    customHeaders: {
      'x-shutterstock-application': 'Widget Example App',
    },
    pages: [
      myImageCollectionsPage,
    ],
  });

  widget.render();

}

A page that shows an image collection

ParameterTypeDescription
component String (Required) Set to ShutterstockWidget.components.ImageCollectionPage
name String (Required) A unique name for the page
props Object The configuration properties for the page
props.items CollectionItemDataList A list of IDs of the assets to show
props.onItemClick onItemClick A callback to run when the user clicks on an asset
props.overlayActions [OverlayAction] The overlay actions for each item
props.pageSubtitle String The subtitle for the page
props.pageTitle String The title for the page
props.showItemId Boolean Whether to show the asset ID when the user hovers the mouse over an asset
props.showMore Boolean Whether to show the "Show More" button when there are more results to paginate through
props.theme CollectionPageTheme The CSS classes for the page

ImageDetailsPage

Example

const myImageDetailsPage = {
  component: ShutterstockWidget.components.ImageDetailsPage,
  name: 'myImageDetailsPage',
  props: {
    showSearchBar: true,
    buttons: [
      {
        label: 'Insert preview',
        icon: '/download-comp.svg',
        onClick: (e, item) => {
          e.preventDefault();
          console.log(`Insert code to preview image ${item.id} here.`);
        },
      },
      {
        label: 'License',
        icon: '/shopping-cart.svg',
        onClick: (e, item) => {
          e.preventDefault();
          widget.navigateTo('myImageLicensingPage', {
            item,
            subscriptions, // Not shown in this example
          });
        },
      },
    ],
    subtitle: 'Details page',
    title: 'Shutterstock UI',
  },
};

const widget = new ShutterstockWidget({
  languageCode: 'en',
  title: 'Shutterstock UI',
  container: document.getElementById('widget-container'),
  key: '<YOUR_APP_CONSUMER_KEY_HERE>',
  pages: [
    mySearchPage, // Not shown in this example
    myImageLicensingPage, // Not shown in this example
    myImageDetailsPage,
  ],
});

widget.render();

A page that shows information about a single image

ParameterTypeDescription
component String (Required) Set to ShutterstockWidget.components.ImageDetailsPage
name String (Required) A unique name for the page
props Object The configuration properties for the page
props.assetInfo ImageResult | VideoResult Information about the image to show on the page
props.breadcrumbs [Breadcrumb] An array of breadcrumb links to show at the top of the page
props.buttons [Button] An array of buttons to show on the page
props.item.id Object The ID of an asset to show on the page
props.searchResults [ImageResult] | [VideoResult] An array of results that override the results from the search page, such as if you want to store search results and show those stored results later
props.showSearchBar Boolean Whether to show a search bar on the page; the default is false
props.theme ImageDetailsPageTheme The CSS classes for the page

ImageLicenseHistoryPage

Example

const mockLicenseHistory = {
  total_count: 3,
  page: 1,
  per_page: 2,
  data: [
    {
      id: "2e2342w23r23r",
      user: {
        "username": "ASDFGHJ",
      },
      "license": "premier_digital",
      "download_time": "2020-11-03T14:49:43.000Z",
      "is_downloadable": true,
      "image": {
        id: "1708754152",
        "thumb": "https://image.shutterstock.com/image-vector/cute-cats-vector-illustration-black-450w-1708754152.jpg",
        "format": {
          "size": "vector",
        },
      },
      "subscription_id": "s123456789",
      "metadata": {
        "purchase_order": "QW-123",
        "job": "",
        "client": "",
        "other": "",
      },
    },
    {
      id: "234234wsdsadasdqr23re",
      user: {
        "username": "ASDFGHJ"
      },
      "license": "premier_digital",
      "download_time": "2020-11-03T14:49:43.000Z",
      "is_downloadable": true,
      "image": {
        id: "345821210",
        "format": {
          "size": "huge",
        },
      },
      "subscription_id": "s1234567789",
      "metadata": {
        "purchase_order": "QW-123",
        "job": "",
        "client": "",
        "other": "",
      },
    },
  ],
};

const mockNextPageLicenseHistory = {
  "total_count": 3,
  "page": 2,
  "per_page": 20,
  "data": [
    {
      id: "asdasdasdasdsadsa",
      user: {
        "username": "ABCD"
      },
      "license": "standard",
      "description": "Standard",
      "download_time": "2018-05-23T14:41:53.000Z",
      "is_downloadable": false,
      "image": {
        id: "409679020",
        "format": {
          "size": "huge"
        }
      },
      "subscription_id": "s6719023902",
      "metadata": {
        "purchase_order": "-",
        "other": "-"
      }
    },
    ],
  };

window.onload = () => {
  const attachClickEventListeners = () => {
    // Attach click event listener on Home
    document.getElementById('home').addEventListener('click', () => {
      widget.navigateTo('mySearchPage');
    });

    // Attach click event listener on Downloads
    document.getElementById('license-history-page-link').addEventListener('click', async () => {
      // Fetch license history from backend.
      const licenseHistory = mockLicenseHistory || await fetch('YOUR_BACKEND_ROUTE_TO_FETCH_LICENSE_HISTORY');

      widget.navigateTo('myImageLicenseHistoryPage', {
        licenseHistory: licenseHistory,
      });
    });
  };

  attachClickEventListeners();

  const myImageLicenseHistoryPage  = {
    name: 'myImageLicenseHistoryPage',
    component: ShutterstockWidget.components.ImageLicenseHistoryPage,
    props: {
      onLicenseHistoryItemClick: (item) => {
        // Navigate to the image details page (not included in this example)
        e.preventDefault();
        widget.navigateTo('myImageDetailsPage', {
          item,
        });
      },
      getMoreResults: async (page) => {
        // Fetch more results from the server-side code
        const nextResults = mockNextPageLicenseHistory || await getLicenseHistory('Your backend route to fetch more license history results');
        return nextResults;
      },
      licenseHistory: {},
    }
  };

  const widget = new ShutterstockWidget({
    languageCode: 'en',
    title: 'Shutterstock UI',
    container: document.getElementById('widget-container'),
    showMore: true,
    key: '<YOUR_APP_CONSUMER_KEY_HERE>',
    customHeaders: {
      'x-shutterstock-application': 'Widget Example App',
    },
    pages: [
      myImageLicenseHistoryPage,
      myImageDetailsPage, //Not included in this example
    ],
  });

  widget.render();

}

A page that is intended to show the assets that the user has already licensed, but it can show any list of assets that you pass to its props.LicenseHistory parameter

ParameterTypeDescription
component String (Required) Set to ShutterstockWidget.components.ImageLicenseHistoryPage
name String (Required) A unique name for the page
props Object The configuration properties for the page
props.getMoreResults getMoreResults A callback to run when the user clicks the link to show more results
props.licenseHistory LicenseHistory The list of assets to show on the page
props.onLicenseHistoryItemClick onLicenseHistoryItemClick A callback to run when the user clicks an asset
props.overlayActions [OverlayAction] The overlay actions for each item
props.pageTitle String The title for the page
props.theme ImageLicenseHistoryPageTheme The CSS classes for the page

ImageLicensingPage

Example

const myImageLicensingPage = {
  name: 'myImageLicensingPage',
  component: ShutterstockWidget.components.ImageLicensingPage,
  props: {
    subscriptions: [],
    buttons: [
      {
        label: 'License',
        icon: '/shopping-cart.svg',
        isPrimary: true,
        onClick: async (e, item, props) => {
          e.preventDefault();
          await fetch('Your backend route to license images');
        },
      },
    ],
    subtitle: 'Licensing page',
    title: 'Shutterstock UI',
  },
};

const overlayActions = [
  {
    label: 'License',
    icon: '/shopping-cart.svg',
    onClick: async (e, item) => {
      e.preventDefault();
      // Fetch user subscriptions
      const subscriptions = await fetch('YOUR_BACKEND_ROUTE_TO_FETCH_SUBSCRIPTIONS');
      widget.navigateTo('myImageLicensingPage', {
        subscriptions,
        item,
      });
    },
  },
];

const mockSubscriptions = [{
  id: 's87654321',
  license: 'premier',
  description: 'Premier Account',
  price_per_download: {
    local_amount: 26,
    local_currency: 'USD'
  },
  formats: [
    {
      size: 'medium',
      details_for_image: {
        width: 1000,
        height: 562,
        dpi: 300,
      },
    },
    {
      size: 'vector',
      format: 'eps',
      media_type: 'image',
      description: 'Vector'
    },
  ],
}];

const mySearchPage = {
  name: 'mySearchPage',
  component: ShutterstockWidget.components.SearchPage,
  props: {
    mediaType: 'images',
    onItemClick: (e, item) => {
      e.preventDefault();
      widget.navigateTo('myImageLicensingPage', {
        subscriptions: mockSubscriptions,
        item,
      });
    },
    overlayActions,
    assetsPerPage: 4,
    showMore: true,
    showSearchBar: true,
    subtitle: 'Search page',
    title: 'Shutterstock UI',
  }
};

const widget = new ShutterstockWidget({
  languageCode: 'en',
  title: 'Shutterstock UI',
  container: document.getElementById('widget-container'),
  showMore: true,
  key: '<YOUR_APP_CONSUMER_KEY_HERE>',
  pages: [
    myImageLicensingPage,
    mySearchPage,
  ],
});

widget.render();

A page that lets the user select a subscription and license an image

ParameterTypeDescription
component String (Required) Set to ShutterstockWidget.components.ImageLicensingPage
name String (Required) A unique name for the page
props Object The configuration properties for the page
props.breadcrumbs [Breadcrumb] An array of breadcrumb links to show at the top of the page
props.buttons [Button] (Required) An array of buttons to show on the page
props.item.id Object The ID of an asset to show on the page
props.searchResults [ImageResult] | [VideoResult] An array of results that override the results from the search page, such as if you want to store search results and show those stored results later
props.showSearchBar Boolean Whether to show a search bar on the page; the default is false
props.subscriptions [Object] (Required) An array of subscriptions to allow the user to select from on the page; for information about the schema, see the Subscription schema in the Shutterstock API reference
props.theme ImageLicensingPageTheme The CSS classes for the page

SearchPage

Example: Creating a widget

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

    <script>
      window.onload = () => {
        const mySearchPage = {
          name: 'mySearchPage',
          component: ShutterstockWidget.components.SearchPage,
          props: {
            languageCode: 'en',
            mediaType: 'images',
            license: ['commercial'],
            showSearchBar: true,
            showMore: true,
            title: 'Search page',
            subtitle: 'Shutterstock UI',
            onItemClick: (event, item) => {
              event.preventDefault();
              console.log(`You clicked ${item.description}`);
            },
            onSearch: (search) => {
              console.log(`Your search found ${search.total_results} results. The first result is "${search.results[0].description}"`);
            },
          }
        };

        const widget = new ShutterstockWidget({
          container: document.getElementById('widget-container'),
          key: 'YOUR_API_APP_CONSUMER_KEY',
          customHeaders: {
            'x-shutterstock-application': 'Shutterstock UI Example App',
          },
          pages: [
            mySearchPage,
          ],
        });
        
        widget.render();
      }
    </script>
  </head>
  <body>
    <p id="statusText"></p>
    <div id="widget-container"></div>
  </body>
</html>

A page that lets the user search for images or videos

ParameterTypeDescription
component String (Required) Set to ShutterstockWidget.components.SearchPage
name String (Required) A unique name for the page
props Object An object with the options for the Search Page
props.assetsPerPage Integer Number of assets to display on the page; the default is 26
props.contributor String Show assets with the specified contributor names or IDs
props.dynamicSubtitle Boolean If true, placeholders such as {{TOTAL_COUNT}} and {{SEARCH_TERM}} can be passed in the subtitle; the widget replaces them with the total number of results and the search query
props.dynamicTitle Boolean If 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
props.editorialCountry String A three-character (ISO 3166 Alpha-3) country code to show editorial content for that country
props.emptyResultsSubtitle String Custom subtitle that overrides the EmptySearchResults component subtitle
props.emptyResultsTitle String Custom title that overrides the EmptySearchResults component title; you can include the placeholder {{SEARCH_TERM}} in the title; the widget replaces it with the search query.
props.imageType [String] The types of images to return, such as photo, illustration, or vector; by default, all image types are returned
props.keywordSafeSearch boolean Hide results with potentially unsafe keywords
props.mediaType String (Required) The type of media to show in the widget; valid values are images, videos, and editorial
props.onError onError A callback to run when the API search or widget returns errors; see [Handling errors]{@link #handling-errors}
props.onItemClick onItemClick A callback to run when the user clicks on an asset in the widget
props.onSearch onSearch A callback to run after the search has returned results
props.overlayActions [OverlayAction] A list of overlay actions to put on media thumbnails
props.safe Boolean Enable or disable safe search
props.searchFilters SearchFilters props.for custom search filters
props.searchSuggestions SearchSuggestionConfig settings for search suggestions
props.showItemId Boolean If set to true, the widget shows the asset ID when a user hovers over an asset in the results
props.showMore Boolean Whether to show a pagination button that displays more search results; the default is true
props.showMoreButtonText String Text for the pagination button; the default is "Show more"
props.showSearchBar Boolean Whether to show a search bar on the page; the default is false
props.subtitle String Subtitle of the widget
props.theme SearchPageTheme The CSS classes for the page
props.title String Title of the widget

VideoCollectionPage

Example

const mockVideoCollection = {
  "data": [
    {
      "id": "1053312533",
      "added_time": "2018-10-12T09:46:26-04:00"
    },
    {
      "id": "1054062332",
      "added_time": "2018-10-12T09:46:26-04:00"
    },
    {
      "id": "1060479172",
      "added_time": "2017-08-07T16:40:09-04:00"
    }
  ]
};

const myVideoCollectionsPage = {
  name: 'myVideoCollectionsPage',
  component: ShutterstockWidget.components.VideoCollectionPage,
  props: {
    items: [],
    pageTitle: 'My Video Collection',
    onItemClick: (e, item) => {
      e.preventDefault();
      console.log(
        item
      );
    },
  },
};

window.onload = () => {
  const attachClickEventListeners = () => {
    // Attach click event listener
    document.getElementById('video-collection-page-link').addEventListener('click', async () => {
      // Fetch collection contents from backend
      const videoCollection = mockVideoCollection || await fetch('YOUR_BACKEND_ROUTE_TO_FETCH_COLLECTION_CONTENTS');

      widget.navigateTo('myVideoCollectionsPage', {
        items: videoCollection,
      });
    });
  };

  attachClickEventListeners();

  const widget = new ShutterstockWidget({
    languageCode: 'en',
    title: 'Shutterstock UI',
    container: document.getElementById('widget-container'),
    showMore: true,
    key: '<YOUR_APP_CONSUMER_KEY_HERE>',
    customHeaders: {
      'x-shutterstock-application': 'Widget Example App',
    },
    pages: [
      myVideoCollectionsPage,
    ],
  });

  widget.render();

}

A page that shows a video collection

ParameterTypeDescription
component String (Required) Set to ShutterstockWidget.components.VideoCollectionPage
name String (Required) A unique name for the page
props Object The configuration properties for the page
props.items CollectionItemDataList A list of IDs of the assets to show
props.onItemClick onItemClick A callback to run when the user clicks on an asset
props.overlayActions [OverlayAction] The overlay actions for each item
props.pageSubtitle String The subtitle for the page
props.pageTitle String The title for the page
props.showItemId Boolean Whether to show the asset ID when the user hovers the mouse over an asset
props.showMore Boolean Whether to show the "Show More" button when there are more results to paginate through
props.theme CollectionPageTheme The CSS classes for the page

Callbacks

getMoreResults(page)

Example: Calling the server-side code to return more license history results

const myImageLicenseHistoryPage  = {
  name: 'myImageLicenseHistoryPage',
  component: ShutterstockWidget.components.ImageLicenseHistoryPage,
  props: {
    onLicenseHistoryItemClick: onLicenseHistoryItemClick,
    getMoreResults: getMoreResults,
    licenseHistory: {},
  },
};

function getMoreResults(page) {
  // Fetch more results from the server-side code
  const nextResults = mockNextPageLicenseHistory || await getLicenseHistory('Your backend route to get more license history results');
  return nextResults;
}

The function that runs when the user clicks on the link to show more results in the license history page; it must return more results

ParameterTypeDescription
page Integer The number of the page results that is currently shown on the page, as described in Paging responses in the Shutterstock API reference

Must return: [LicenseHistory]

onClickOverlayAction(event, item, options)

Example: Responding to clicks on overlay actions

const overlayActions = [
  {
    label: 'Insert preview',
    icon: '/download-comp.svg',
    onClick: (e, item) => {
      e.preventDefault();
      console.log(`Inserting preview image:${item.id}`);
    }
  },
  {
    label: 'License',
    icon: '/shopping-cart.svg',
    onClick: (e, item) => {
      e.preventDefault();
      widget.navigateTo('myImageLicensingPage', {
        item,
      });
    }
  },
];

const mySearchPage = {
  name: 'mySearchPage',
  component: ShutterstockWidget.components.SearchPage,
  props: {
    mediaType: 'images',
    overlayActions,
    subtitle: 'Search page',
    title: 'Shutterstock UI',
  }
};

The function that runs when the user clicks an overlay action

ParameterTypeDescription
event Object The JavaScript event object that represents the click event
item ImageResult | VideoResult An object with information about the asset that the user clicked
options Object An object that contains browser options

onError(error)

Example: Handling errors

const mySearchPage = {
  name: 'mySearchPage',
  component: ShutterstockWidget.components.SearchPage,
  props: {
    mediaType: 'images',
    onError,
    subtitle: 'Search page',
    title: 'Shutterstock UI',
  }
};

function onError(error) {
  console.error(error.message);
  console.error(error.errors);
}

The function that runs when the widget throws an error

ParameterTypeDescription
error Object Information about one or more errors
error.errors [Object] An array of more specific information about the error
error.message String A textual description of the error

onItemClick(event, item)

Example: Responding to clicks

const mySearchPage = {
  name: 'mySearchPage',
  component: ShutterstockWidget.components.SearchPage,
  props: {
    mediaType: 'images',
    onItemClick,
    subtitle: 'Search page',
    title: 'Shutterstock UI',
  }
};

function onItemClick(e, item) {
  e.preventDefault();
  console.log(item.description);
}

The function that runs when a user clicks an image or video

ParameterTypeDescription
event Object The JavaScript event object that represents the click event
item ImageResult | VideoResult 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

onLicenseHistoryItemClick(item, options)

Example: Responding to clicks on assets on the license history page

const myImageLicenseHistoryPage = {
  name: 'myImageLicenseHistoryPage',
  component: ShutterstockWidget.components.ImageLicenseHistoryPage,
  props: {
    onLicenseHistoryItemClick: onLicenseHistoryItemClick,
    getMoreResults: getMoreResults,
    licenseHistory: {},
  },
};

function onLicenseHistoryItemClick(item) {
  e.preventDefault();
  widget.navigateTo('myImageDetailsPage', {
    item,
  });
};

The function that runs when the user clicks an asset on the license history page

ParameterTypeDescription
item ImageResult | VideoResult 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
options Object An object that contains browser options

onSearch(response)

Example: Responding to search results

const mySearchPage = {
  name: 'mySearchPage',
  component: ShutterstockWidget.components.SearchPage,
  props: {
    mediaType: 'images',
    editorialCountry: "USA",
    onSearch,
    subtitle: 'Search page',
    title: 'Shutterstock UI',
  }
};

function onSearch({ searchTerm, searchId, total_results, results }) {
  console.log(`Your search for ${searchTerm} found ${total_results} results. The first result is "${results[0].description}"`);
}

The function that runs when the widget runs a search

ParameterTypeDescription
response Object An object with information about the search and its results
response.results [ImageResult] | [VideoResult] The array of search results
response.searchId String The ID of the API search
response.searchTerm String The search query text
response.total_results Integer The number of results

searchSuggestionTextProvider()

Example: Getting text to provide search suggestions for

const mySearchPage = {
  name: 'mySearchPage',
  component: ShutterstockWidget.components.SearchPage,
  props: {
    mediaType: 'images',
    editorialCountry: "USA",
    textProvider: searchSuggestionTextProvider,
    subtitle: 'Search page',
    title: 'Shutterstock UI',
  }
};

function searchSuggestionTextProvider() {
  return document.getElementById('div#content').textContent;
}

The function that provides the text to get search suggestions from

Parameters: None

Must return: String

Types

Example

{
  label: "Home page",
  to: "/",
}

A breadcrumb link to show at the top of the page

FieldTypeDescription
label String (Required) The text for the link
to String The target path for the link

Button

Example

{
  label: 'Insert preview',
  icon: '/download-comp.svg',
  onClick: (e, item) => {
    e.preventDefault();
    console.log(`Insert code to preview image ${item.id} here.`);
  },
}

A button to show on a page

FieldTypeDescription
icon String The path to the icon
isPrimary Boolean Whether this button is the main button for the page
label String (Required) The label text
onClick onClickButton The onClick callback

CollectionItem

An asset in a collection; this object's schema matches the CollectionItem schema

FieldTypeDescription
added_time String The date the item was added to the collection
id String (Required) the ID of the item
media_type String The media type of the item, such as image, video, or audio

CollectionItemDataList

Example

{
  "data": [
    {
      "id": "256220611",
      "added_time": "2018-10-12T09:46:26-04:00"
    },
    {
      "id": "91378538",
      "added_time": "2018-10-12T09:46:26-04:00"
    },
    {
      "id": "536372056",
      "added_time": "2017-08-07T16:40:09-04:00"
    }
  ]
}

A list of assets in a collection; this object's schema matches the CollectionItemDataList object that the GET /v2/images/collections/{id}/items and GET /v2/videos/collections/{id}/items endpoints return

FieldTypeDescription
data [CollectionItem] A list of items in the collection
page Integer The page number of the results
per_page Integer The number of results per page
total_count Integer The total number of results

CollectionPageTheme

Example

{
  header: {
    container: 'containerCssClass',
    subtitle: 'subtitleCssClass',
    title: 'titleCssClass',
  },
  emptyCollection: 'emptyCollectionCssClass',
}

Classes for the image and video collection pages

FieldTypeDescription
emptyCollection String The classes for the header on the screen that shows when a collection has no assets
header Object The classes for the header
header.container String The class for the container div element for the header
header.subtitle String The class for the subtitle
header.title String The class for the title

ImageDetailsPageTheme

Example

{
  breadcrumb: {
    breadcrumbContainer: 'breadcrumbContainerCssClass',
    link: 'breadcrumbLinkCssClass',
    text: 'breadcrumbTextCssClass',
    breadcrumbArrow: 'breadcrumbArrowCssClass',
  },
  iconClass: 'iconClassCssClass',
  ctaLabelClass: 'ctaLabelClassCssClass',
}

Classes for the image details page

FieldTypeDescription
breadcrumb Object Classes for the breadcrumb section
breadcrumb.breadcrumbArrow String The class for the arrow that connects breadcrumb links
breadcrumb.breadcrumbContainer String The class for the breadcrumbs
breadcrumb.link String The class for the breadcrumb links
breadcrumb.text String The class for the breadcrumb link text
ctaLabelClass String The class for the Call to Action button
iconClass String The class for the icon in the Call to action button

ImageLicenseHistoryPageTheme

Example

{
  container: 'containerCssClass',
  imageId: 'imageIdCssClass',
  size: 'sizeCssClass',
  date: 'dateCssClass',
}

Classes for the license history page

FieldTypeDescription
container String The class for the container for the main page content
date String The class for the date that each asset was licensed
imageId String The class for the ID text for each asset
size String The class for the size of each asset

ImageLicensingPageTheme

Example

{
  breadcrumb: {
    breadcrumbContainer: 'breadcrumbContainerCssClass',
    link: 'breadcrumbLinkCssClass',
    text: 'breadcrumbTextCssClass',
    breadcrumbArrow: 'breadcrumbArrowCssClass',
  },
  iconClass: 'iconClassCssClass',
  ctaLabelClass: 'ctaLabelClassCssClass',
}

Classes for the licensing image page

FieldTypeDescription
breadcrumb Object Classes for the breadcrumb section
breadcrumb.breadcrumbArrow String The class for the arrow that connects breadcrumb links
breadcrumb.breadcrumbContainer String The class for the breadcrumbs
breadcrumb.link String The class for the breadcrumb links
ctaLabelClass String The class for the Call to Action button
iconClass String The class for the icon in the Call to action button

ImageResult

Example

{
  "id": "526400839",
  "aspect": 1.1102,
  "src": "https://image.shutterstock.com/display_pic_with_logo/164693082/526400839/stock-photo-light-blue-flower-on-a-white-background-isolated-with-clipping-path-closeup-big-shaggy-flower-526400839.jpg",
  "slug": "light blue flower on a white  background isolated  with clipping path. Closeup. big shaggy  flower. for design.  Dahlia.-526400839",
  "link": "",
  "description": "light blue flower on a white  background isolated  with clipping path. Closeup. big shaggy  flower. for design.  Dahlia.",
  "preview_1000": {
    "url": "https://ak.picdn.net/shutterstock/photos/526400839/watermark_1000/7f8d92d1e15dead16b940ee7a3e89777/preview_1000-526400839.jpg",
    "width": 1000,
    "height": 901,
  },
  "preview_1500": {
    "url": "https://image.shutterstock.com/z/stock-photo-light-blue-flower-on-a-white-background-isolated-with-clipping-path-closeup-big-shaggy-flower-526400839.jpg",
    "width": 1500,
    "height": 1351,
  },
  "height": 405,
  "url": "https://image.shutterstock.com/display_pic_with_logo/164693082/526400839/stock-photo-light-blue-flower-on-a-white-background-isolated-with-clipping-path-closeup-big-shaggy-flower-526400839.jpg",
  "width": 450,
}

An image search result

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

ImageTypeFilter

Example

{
  label: 'Pictures of flowers',
  assetType: 'images',
  params: {
    query: "flowers",
  },
}

A custom image search filter for the Filters drawer

FieldTypeDescription
assetType String Specify "images"
label String (Required) A text label for the filter
params Object (Required) The parameters for the custom search
params.image_type String The type of image: "photo," "illustration," or "vector"
params.orientation String The orientation of the images: "horizontal," "vertical," or "all"
params.query String (Required) The query text for the search

License

Example

{
  id: "2e2342w23r23r",
  user: {
    "username": "ASDFGHJ",
  },
  "license": "premier_digital",
  "download_time": "2020-11-03T14:49:43.000Z",
  "is_downloadable": true,
  "image": {
    id: "1708754152",
    "thumb": "https://image.shutterstock.com/image-vector/cute-cats-vector-illustration-black-450w-1708754152.jpg",
    "format": {
      "size": "vector",
    },
  },
  "subscription_id": "s123456789",
  "metadata": {
    "purchase_order": "QW-123",
    "job": "",
    "client": "",
    "other": "",
  },
}

An asset that the user has licensed; this object's schema matches the DownloadHistory object that the GET /v2/images/licenses endpoint returns

FieldTypeDescription
download_time String Date the media was downloaded the first time
id String ID of the download
image Object Information about the downloaded media
image.format Object Information about the format of the image
image.id String The ID of the image
image.thumb String A link to a thumbnail of the image
is_downloadable Boolean Specifies if the media is downloadable via its respective downloads endpoint
license String The name of the license
metadata Object The metadata that was passed in the original licensing request
subscription_id String The ID of the subscription used to perform this download
user Object Information about the user that licensed the image

LicenseHistory

Example

{
  total_count: 3,
  page: 1,
  per_page: 2,
  data: [
    {
      id: "2e2342w23r23r",
      user: {
        "username": "ASDFGHJ",
      },
      "license": "premier_digital",
      "download_time": "2020-11-03T14:49:43.000Z",
      "is_downloadable": true,
      "image": {
        id: "1708754152",
        "thumb": "https://image.shutterstock.com/image-vector/cute-cats-vector-illustration-black-450w-1708754152.jpg",
        "format": {
          "size": "vector",
        },
      },
      "subscription_id": "s123456789",
      "metadata": {
        "purchase_order": "QW-123",
        "job": "",
        "client": "",
        "other": "",
      },
    },
    {
      id: "234234wsdsadasdqr23re",
      user: {
        "username": "ASDFGHJ",
      },
      "license": "premier_digital",
      "download_time": "2020-11-03T14:49:43.000Z",
      "is_downloadable": true,
      "image": {
        id: "345821210",
        "format": {
          "size": "huge"
        },
      },
      "subscription_id": "s1234567789",
      "metadata": {
        "purchase_order": "QW-123",
        "job": "",
        "client": "",
        "other": "",
      },
    },
  ],
}

A list of assets that the user has licensed; this object's schema matches the DownloadHistoryDataList object that the GET /v2/images/licenses endpoint returns

FieldTypeDescription
data [License] A list of licenses
page Integer The page number of the results
per_page Integer The number of results per page
total_count Integer The total number of results

OverlayAction

Example

{
  icon: '/icon.svg',
  label: 'Hello',
  onClick: (e, item) => {
    e.preventDefault();
    console.log(item);
  },
}

Clickable action icon to overlay on search results

FieldTypeDescription
overlayAction.icon String (Required) The path to the icon
overlayAction.label String (Required) The label text
overlayAction.onClick onClickOverlayAction (Required) onClick callback

Page

Example

{
  name: 'mySearchPage', // Page name
  component: ShutterstockWidget.components.SearchPage, // Component for page
  props: {
    mediaType: 'images',
    showSearchBar: true,
  }
}

Configuration object for a page (route) in the widget

FieldTypeDescription
component Object (Required) The component to render on the page
name String (Required) Name of the page
props Object Props that get passed to the page component

searchBarDropdownFilter

Example

{
  label: 'Vertical mountains',
  assetType: 'images',
  params: {
    query: "mountains",
    orientation: "vertical",
  },
}

A custom filter for the search bar

FieldTypeDescription
assetType String The type of asset, such as "images," "videos," or "editorial"
label String A text label for the filter
params Object The parameters for the custom search
params.orientation String The orientation of the images: "horizontal," "vertical," or "all"
params.query String The query text for the search

searchBarDropdownFilter

Example

{
  label: 'Vertical mountains',
  assetType: 'images',
  params: {
    query: "mountains",
    orientation: "vertical",
  },
}

A custom filter for the search bar

FieldTypeDescription
assetType String The type of asset, such as "images," "videos," or "editorial"
label String A text label for the filter
params Object The parameters for the custom search
params.orientation String The orientation of the images: "horizontal," "vertical," or "all"
params.query String The query text for the search

SearchFilters

Example

const searchFilters =  {
  showFilterDrawer: true,
  images: {
    orientationFilter: true,
    imageTypeFilter: [
      {
        label: 'Pictures of flowers',
        assetType: 'images',
        params: {
          query: "flowers",
        },
      },
    ],
  },
  searchBarDropdownFilters: [
    {
      label: 'Images',
      assetType: 'images',
    },
    {
      label: 'Footage',
      assetType: 'videos',
    },
    {
      label: 'Editorial',
      assetType: 'editorial',
    },
    {
      label: 'Vertical mountains',
      assetType: 'images',
      params: {
        query: "mountains",
        orientation: "vertical",
      },
    },
  ],
};

Configuration for custom search filters

FieldTypeDescription
images Object Options for image searches
images.imageTypeFilters [ImageTypeFilter] An array of custom search filters to show in the Filters drawer
images.orientationFilter Boolean Whether to show the option to filter images by horizontal or vertical orentation
searchBarDropdownFilters [searchBarDropdownFilter] An array of custom search filters to show in the search bar drop-down menu
showFilterDrawer Boolean Whether to show the Filters drawer with the available filters next to the search bar

SearchPageTheme

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',
  },
}

Classes for the search page

FieldTypeDescription
emptySearchResults String The classes for the header on the screen that shows when a search returns no results
emptySearchResults.container String The class for the container div element for the header
emptySearchResults.subtitle String The class for the subtitle
emptySearchResults.title String The class for the title
error Object Classes for the screen that shows when the API returns an error
error.container String The class for the container div element for the header
error.subtitle String The class for the subtitle
error.title String The class for the title
header Object The classes for the header on a normal search page
header.container String The class for the container div element for the header
header.subtitle String The class for the subtitle
header.title String The class for the title
pagination Object An object with classes for the Show more button at the bottom of the results
pagination.container String The class for the container div element for the Show More button
pagination.showMore String The class for the Show More button
searchBar Object An object with classes for the search bar
searchBar.container String The class for the container div element for the search bar
searchBar.formControlInput String The class for the form input element
searchBar.inputGroup String The class for the input group that contains the search query field and submit button
searchBar.searchButton String The class for the submit button
searchBar.searchForm String The class for the form element
searchBar.searchIcon String The class for the submit button
searchBar.searchIconContainer String The class for the container for the submit button

SearchSuggestionConfig

Example

{
  searchSuggestions: {
    numberOfSuggestionRows: 3,
    enable: true,
    textProvider: () => {
      // Text to use to provide recommendations
      return "Planting flowers is a great way to make springtime more beautiful.";
    },
  },
};

Options for getting image suggestions from text

FieldTypeDescription
searchSuggestions.enable String Set to true to enable search suggestions
searchSuggestions.numberOfSuggestionRows Integer The number of rows of results to show
searchSuggestions.textProvider searchSuggestionTextProvider (Required) A function that returns the text to use

VideoResult

Example

{
  "id": "1054726028",
  "link": "",
  "slug": "Drone following a traditional Thai long tail boat in Crystal clear waters-1054726028",
  "description": "Drone following a traditional Thai long tail boat in Crystal clear waters",
  "preview": {
    "webm": "https://ak.picdn.net/shutterstock/videos/1054726028/preview/stock-footage-drone-following-a-traditional-thai-long-tail-boat-in-crystal-clear-waters.webm",
    "mp4": "https://ak.picdn.net/shutterstock/videos/1054726028/preview/stock-footage-drone-following-a-traditional-thai-long-tail-boat-in-crystal-clear-waters.mp4"
  },
  "width": 533.4,
  "height": 300,
  "src": "https://ak.picdn.net/shutterstock/videos/1054726028/thumb/1.jpg",
  "url": "https://ak.picdn.net/shutterstock/videos/1054726028/thumb/1.jpg"
}

A video search result

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