
Current version: 2.3.2
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 and other related features 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:
- Go to https://shutterstock.com/account/developers/apps.
- Create or edit an app you want to use with the widget.
- In the Referrer field, specify a comma-separated list of host names that you will host the widget on.
- Make sure that each referrer host name is also listed in the Callback URL field.
- 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:
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.3.2/static/css/sstk-widget.css">
<script src="https://api-cdn.shutterstock.com/2.3.2/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.
-
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.
-
Create an HTML element to contain the widget and give it an ID, such as
widget-container
. -
Create the the widget object.
-
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.
-
Add one or more pages. For information about the different pages that are available, see Customizing pages.
-
Call the widget's
render()
method or the search page'ssearch()
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:
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'),
key: '<YOUR_APP_CONSUMER_KEY_HERE>',
pages: [
myImageDetailsPage,
mySearchPage, // Not shown in this example
]
});
The UI widget can show these pages:
Page | Page type |
---|---|
Search page | ShutterstockWidget.components.SearchPage |
Reverse image search page | ShutterstockWidget.components.ReverseImageSearchPage |
Collection pages | ShutterstockWidget.components.ImageCollectionPage and ShutterstockWidget.components.VideoCollectionPage |
Featured collection pages | ShutterstockWidget.components.FeaturedImageCollectionPage and ShutterstockWidget.components.FeaturedVieoCollectionPage |
Details pages | ShutterstockWidget.components.ImageDetailsPage or ShutterstockWidget.components.VideoDetailsPage |
Licensing pages | ShutterstockWidget.components.ImageLicensingPage and ShutterstockWidget.components.VideoLicensingPage |
License history pages | ShutterstockWidget.components.ImageLicenseHistoryPage or ShutterstockWidget.components.VideoLicenseHistoryPage |
To show a page in the widget, create an object of the page type, specify its properties including 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();
let targetPage;
switch (item.media_type) {
case 'image':
targetPage = 'myImageDetailsPage';
break;
case 'video':
targetPage = 'myVideoDetailsPage';
break;
}
widget.navigateTo(targetPage, {
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
myVideoDetailsPage, // 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
, specify the properties for the page, and add it to the widget's pages
array.
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.
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.
Reverse image search page
Example reverse image search page
const myReverseImageSearchPage = {
name: 'myReverseImageSearchPage',
component: ShutterstockWidget.components.ReverseImageSearchPage,
props: {
onItemClick: (e, item) => {
e.preventDefault();
widget.navigateTo('myImageDetailsPage', {
item,
});
},
showMore: true,
title: 'Reverse image search',
ctaTitle: 'Upload image',
dragDropTitle: 'Drag and drop an image to find similar images',
dropTitle: 'Drop the image here to find similar images',
}
};
const widget = new ShutterstockWidget({
languageCode: 'en',
container: document.getElementById('widget-container'),
key: 'YOUR_API_APP_CONSUMER_KEY',
pages: [
myReverseImageSearchPage,
myImageDetailsPage, // Not shown in this example
],
});
widget.render();
The reverse image search page allows users to upload an image and see similar images by using Shutterstock's computer vision search.
You can also set the page to programmatically search for an image by encoding it in base 64 and setting it as the value of the props.base64Image
parameter.
To create a reverse image search page, create an object of the type ShutterstockWidget.components.ReverseImageSearchPage
, specify the properties for the page, and add it to the widget's pages
array.
For more information about computer vision search, including its limitations, see Computer vision search in the Shutterstock API reference.
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:
- Create an object of the type
ShutterstockWidget.components.ImageCollectionPage
orShutterstockWidget.components.VideoCollectionPage
and specify the properties for the page. - Add the page to the widget's
pages
array. - 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.
- 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
orGET /v2/videos/collections/{id}/items
endpoint. - 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
orGET /v2/videos/collections/{id}/items
endpoint to the collection page'sprops.items
parameter.
Featured collection pages
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:
- Create an object of the type
ShutterstockWidget.components.FeaturedImageCollectionPage
orShutterstockWidget.components.FeaturedVideoCollectionPage
and specify the properties for the page. - Add the page to the widget's
pages
array. - 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.
- Pass the ID of the featured collection to the page as an integer.
- To get the IDs of featured collections, use the GET /v2/images/collections/featured or
GET /v2/videos/collections/featured
endpoints.
- To get the IDs of featured collections, use the GET /v2/images/collections/featured or
Details pages
Example image details page
const myImageDetailsPage = {
component: ShutterstockWidget.components.ImageDetailsPage,
name: 'myImageDetailsPage',
props: {
bindNavigation: false,
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();
const subscriptions = await fetch('YOUR_BACKEND_ROUTE_TO_FETCH_SUBSCRIPTIONS');
widget.navigateTo('myImageLicensingPage', {
subscriptions,
item,
});
},
},
],
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 a page that shows details about a selected image or video, create an object of the type ShutterstockWidget.components.ImageDetailsPage
or ShutterstockWidget.components.VideoDetailsPage
, specify the properties for the page, and add it to the widget's pages
array.
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
or ShutterstockWidget.components.VideoDetailsPage
page component.
Licensing pages
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 = mockImageSubscriptions || await fetch('YOUR_BACKEND_ROUTE_TO_FETCH_SUBSCRIPTIONS');
widget.navigateTo('myImageLicensingPage', {
subscriptions,
item,
});
},
},
];
const mockImageSubscriptions = [
{
id: 's87654321',
license: 'premier',
description: 'Premier Account',
asset_type: 'images',
price_per_download: {
local_amount: 26,
local_currency: 'USD'
},
formats: [
{
size: 'medium',
format: 'jpg',
media_type: 'image',
},
{
size: 'vector',
format: 'eps',
media_type: 'image',
description: 'Vector'
},
{
size: 'huge',
format: 'jpg',
media_type: 'image',
description: 'huge'
}
],
}
];
const mySearchPage = {
name: 'mySearchPage',
component: ShutterstockWidget.components.SearchPage,
props: {
mediaType: 'images',
onItemClick: (e, item) => {
e.preventDefault();
const subscriptions = mockImageSubscriptions || await fetch('YOUR_BACKEND_ROUTE_TO_FETCH_SUBSCRIPTIONS');
widget.navigateTo('myImageLicensingPage', {
subscriptions,
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 licensing pages show the user an image or video and the options for licensing it, including the available sizes and the user's active subscriptions.
To set up this page, create an object of the type ShutterstockWidget.components.ImageLicensingPage
or ShutterstockWidget.components.VideoLicensingPage
, specify the properties for the page, and add it to the widget's pages
array.
For an example of this page and information about licensing assets with the widget, see Licensing.
License history pages
Example image license history page
const mockImageLicenseHistory = {
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 mockNextPageImageLicenseHistory = {
"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
document.getElementById('image-license-history-page-link').addEventListener('click', async () => {
// Fetch license history from backend.
const licenseHistory = mockImageLicenseHistory || 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 = mockNextPageImageLicenseHistory || 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 does not automatically retrieve the assets in the user's license history; you must create server-side code that retrieves that history.
Follow these general steps to set up a license history page:
- Create an object of the type
ShutterstockWidget.components.ImageLicenseHistoryPage
orShutterstockWidget.components.VideoLicenseHistoryPage
and specify the properties for the page, including theprops.onLicenseHistoryItemClick
andprops.getMoreResults
callbacks that respond to user actions on the page. - Add the page to the widget's
pages
array. - 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.
- 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
orGET /v2/videos/licenses
endpoint. - Pass the license history to the page.
You can pass the response from the
GET /v2/images/licenses
orGET /v2/videos/licenses
endpoint to the license history page'sprops.licenseHistory
parameter.
Theming pages
Setting dark mode
const widget = new ShutterstockWidget({
languageCode: 'en',
title: 'Shutterstock UI',
container: document.getElementById('widget-container'),
key: '<YOUR_APP_CONSUMER_KEY_HERE>',
themeMode: 'light',
pages: [
mySearchPage, // Not shown in this example
]
});
You can set the widget to dark mode or light mode with the themeMode
parameter.
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 individual 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:
- cs
- da
- de
- el
- en
- es
- fi
- fr
- hu
- id
- it
- ja
- ko
- nb
- nl
- pl
- pt
- ro
- ru
- sv
- th
- tr
- vi
- zh
- zh-Hant
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.
category
: The ID or name of a Shutterstock-defined category; see GET /v2/images/categories in the API referencecontributor
: An array of contributor names or IDs to show images from those contributorscontributor_country
: An array of two character country codes to show images from contributors in those countriesimage_type
: An array of one or more image types, including "photo," "illustration," and "vector"keyword_safe_search
: Hide results with potentially unsafe keywordslanguage
: The two-character language code to interpret thequery
parameter in; see Localizing searches in the API referencelicense
: Filter the media according to one or more license types; valid values are "commercial", "editorial"orientation
: The orientation of the image, including "horizontal" and "vertical"page
: The page number of the resultspeople_number
: An integer number of people in the image, from 0 to 4per_page
: The number of results to show per pagequery
: One or more search terms separated by spaces; you can use NOT to filter out images that match a termsafe
: Enable or disable safe searchsort
: 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 referenceduration_from
: The minimum duration of the video in secondsduration_to
: The maximum duration of the video in secondskeyword_safe_search
: Hide results with potentially unsafe keywordslanguage
: The two-character language code to interpret thequery
parameter in; see Localizing searches in the API referencelicense
: Filter the media according to one or more license types; valid values are "commercial", "editorial"page
: The page number of the resultsper_page
: The number of results to show per pagequery
: One or more search terms separated by spaces; you can use NOT to filter out videos that match a termresolution
: The resolution of the video, including "4k," "standard_definition," and "high_definition"safe
: Enable or disable safe searchsort
: 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 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:
mediaType
: Set to "editorial"editorialCountry
: Set to the three-character (ISO 3166 Alpha-3) country code for your country
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:
numberOfSuggestionRows
: The number of rows of results to show.enable
: Whether to enable or disable the suggestions.textProvider
: A function that returns the text to use. You can use static text or retrieve text from somewhere else on the page.
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.
Using reverse image search
Example reverse image search page
const myReverseImageSearchPage = {
name: 'myReverseImageSearchPage',
component: ShutterstockWidget.components.ReverseImageSearchPage,
props: {
onItemClick: (e, item) => {
e.preventDefault();
widget.navigateTo('myImageDetailsPage', {
item,
});
},
showMore: true,
title: 'Reverse image search',
ctaTitle: 'Upload image',
dragDropTitle: 'Drag and drop an image to find similar images',
dropTitle: 'Drop the image here to find similar images',
}
};
const widget = new ShutterstockWidget({
languageCode: 'en',
container: document.getElementById('widget-container'),
key: 'YOUR_API_APP_CONSUMER_KEY',
pages: [
myReverseImageSearchPage,
myImageDetailsPage, // Not shown in this example
],
});
widget.render();
The widget provides a page that uses Shutterstock's computer vision search to provide images that are similar to an image that you or the page user specifies.
To set up reverse image search, create an object of the type ShutterstockWidget.components.ReverseImageSearchPage
, specify the properties for the page, and add it to the widget's pages
array.
To allow users to upload images to use in reverse image search, set the page's props.dragDropTitle
, props.dropTitle
, and props.ctaTitle
parameters to set the text for the reverse image search UI.
The page automatically shows the results when the user uploads an image.
To control which image the page uses, encode the image in base 64 and set the resulting string as the value of the props.base64Image
parameter.
The page automatically shows the search results for that image.
For more information about computer vision search, including its limitations, see Computer vision search in the Shutterstock API reference.
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:
searchTerm
: The search query textsearchId
: The ID of the API searchtotal_results
: The number of resultsresults
: The array of search results. For information about the search results, see ImageResult and VideoResult.
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:
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 theresults
array in theonSearch
callback.
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();
const subscriptions = await fetch('YOUR_BACKEND_ROUTE_TO_FETCH_SUBSCRIPTIONS');
widget.navigateTo('myImageLicensingPage', {
subscriptions,
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.
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
To license images or video, you add pages that guide the user through the process of viewing an asset, 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:
- Create an image or video details page, which is an object of the type
ShutterstockWidget.components.ImageDetailsPage
orShutterstockWidget.components.VideoDetailsPage
. - On the details page, using the
props.button
parameter, create a button that sends the user to the appropriate licensing page. See Setting up the details page. - On the server side, using the Shutterstock API, retrieve information about the user's subscriptions.
- Pass the information about the asset and information about the user's subscriptions to the appropriate licensing page.
- Create an image or video licensing page, which is an object of the type
ShutterstockWidget.components.ImageLicensingPage
orShutterstockWidget.components.VideoLicensingPage
. See Setting up the licensing page. - 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 asset or run some other task.
- On the server side or the client side, download the asset or handle the file in some other way.
Setting up the 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 details page. The example in the right-hand column includes a button that sends the user to the image licensing page and passes information about the asset that the user clicked and the subscriptions that the user has.
To get the correct data to the 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.
This endpoint returns a data
array with a list of the customer's subscriptions; you can pass the contents of this array as the subscriptions
parameter.
The onClick
handler also receives an item
object with information about the image or video that the user clicked.
You can pass this object along with the array of subscriptions to the appropriate licensing page.
These parameters become the licensing page's props.subscriptions
and props.item
properties.
Setting up the 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');
}
},
],
}
};
You can set up the licensing page to do whatever you need to do to license the asset.
The image and video licensing pages are essentially the same.
In most cases, in the onClick
handler for the button, call server-side or backend code to call the Shutterstock API's POST /v2/images/licenses
or POST /v2/videos/licenses
endpoint.
It is up to you to implement this code and what the widget does after the licensing request.
For example, you can configure the widget to show the download link or add the new image or video to the page.
If you pass subscription and size information as described in Setting up the details page, the licensing page automatically shows the subscriptions and asset sizes. For example, the image licensing page shows the dimensions for each size:
Similarly, the video licensing page shows the dimensions for each size:
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.3.2/static/css/sstk-widget.css">
<script src="https://api-cdn.shutterstock.com/2.3.2/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 |
options.themeMode | String |
The mode to render the widget in; valid values are 'light' and 'dark' |
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();
let targetPage;
switch (item.media_type) {
case 'image':
targetPage = myImageDetailsPage;
break;
case 'video':
targetPage = myVideoDetailsPage;
break;
}
widget.navigateTo(targetPage, {
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
myVideoDetailsPage, // 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 |
shutterstockWidget.updateTheme(themeMode)
This function toggles between light mode and dark mode
Param | Type | Default | Description |
---|---|---|---|
themeMode | String |
light |
The theme mode to update to; valid values are 'light' and 'dark' |
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
Parameter | Type | Description |
---|---|---|
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
Parameter | Type | Description |
---|---|---|
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
Parameter | Type | Description |
---|---|---|
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: {
bindNavigation: false,
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();
const subscriptions = await fetch('YOUR_BACKEND_ROUTE_TO_FETCH_SUBSCRIPTIONS');
widget.navigateTo('myImageLicensingPage', {
subscriptions,
item,
});
},
},
],
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
Parameter | Type | Description |
---|---|---|
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.bindNavigation |
Boolean
|
Whether to show navigation buttons under the image; these buttons move to the next or previous image from the images on the previous page, such as a collection page or search results 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 |
ImageResult
|
VideoResult
|
Information about the image 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 mockImageLicenseHistory = {
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 mockNextPageImageLicenseHistory = {
"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
document.getElementById('image-license-history-page-link').addEventListener('click', async () => {
// Fetch license history from backend.
const licenseHistory = mockImageLicenseHistory || 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 = mockNextPageImageLicenseHistory || 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 images that the user has already licensed, but it can show any list of assets that you pass to its props.LicenseHistory
parameter
Parameter | Type | Description |
---|---|---|
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 |
LicenseHistoryPageTheme
|
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 = mockImageSubscriptions || await fetch('YOUR_BACKEND_ROUTE_TO_FETCH_SUBSCRIPTIONS');
widget.navigateTo('myImageLicensingPage', {
subscriptions,
item,
});
},
},
];
const mockImageSubscriptions = [
{
id: 's87654321',
license: 'premier',
description: 'Premier Account',
asset_type: 'images',
price_per_download: {
local_amount: 26,
local_currency: 'USD'
},
formats: [
{
size: 'medium',
format: 'jpg',
media_type: 'image',
},
{
size: 'vector',
format: 'eps',
media_type: 'image',
description: 'Vector'
},
{
size: 'huge',
format: 'jpg',
media_type: 'image',
description: 'huge'
}
],
}
];
const mySearchPage = {
name: 'mySearchPage',
component: ShutterstockWidget.components.SearchPage,
props: {
mediaType: 'images',
onItemClick: (e, item) => {
e.preventDefault();
const subscriptions = mockImageSubscriptions || await fetch('YOUR_BACKEND_ROUTE_TO_FETCH_SUBSCRIPTIONS');
widget.navigateTo('myImageLicensingPage', {
subscriptions,
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 asset
Parameter | Type | Description |
---|---|---|
component |
String
|
(Required) for images set to ShutterstockWidget.components.ImageLicensingPage for videos set to ShutterstockWidget.components.VideoLicensingPage |
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 ]
|
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 |
ReverseImageSearchPage
Example
const myReverseImageSearchPage = {
name: 'myReverseImageSearchPage',
component: ShutterstockWidget.components.ReverseImageSearchPage,
props: {
onItemClick: (e, item) => {
e.preventDefault();
widget.navigateTo('myImageDetailsPage', {
item,
});
},
showMore: true,
title: 'Reverse image search',
ctaTitle: 'Upload image',
dragDropTitle: 'Drag and drop an image to find similar images',
dropTitle: 'Drop the image here to find similar images',
}
};
const widget = new ShutterstockWidget({
languageCode: 'en',
container: document.getElementById('widget-container'),
key: 'YOUR_API_APP_CONSUMER_KEY',
pages: [
myReverseImageSearchPage,
myImageDetailsPage, // Not shown in this example
],
});
widget.render();
A page that runs a reverse image search on an image that the user uploads
Parameter | Type | Description |
---|---|---|
component |
String
|
(Required) Set to ShutterstockWidget.components.ReverseImageSearchPage |
name |
String
|
(Required) A unique name for the page |
props |
Object
|
The configuration properties for the page |
props.base64Image |
String
|
A base 64-encoded image; if provided, the page automatically shows reverse image search results for this image |
props.ctaTitle |
String
|
The label for the button that the user clicks to upload an image |
props.disableDragDrop |
Boolean
|
Set to true to prevent users from dragging and dropping images on the page; default is false |
props.dragDropTitle |
String
|
The title text for the section that allows the user to upload an image |
props.dropTitle |
String
|
The title text that is shown when the user is dragging an image |
props.hideCtaButton |
Boolean
|
Set to true to hide the button that the user clicks to upload an image |
props.hideTotalCount |
Boolean
|
Set to false to hide the number of results; default is false |
props.hideUploadedImageThumb |
Boolean
|
Set to true to hide the thumbnail of the search source image; default is false |
props.onItemClick |
onItemClick
|
A callback to run when the user clicks on an asset |
props.onSearch |
onSearch
|
A callback to run after the search has returned results |
props.overlayActions |
[OverlayAction ]
|
The overlay actions for each item |
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; default is true |
props.showMoreButtonText |
String
|
Text for the pagination button; the default is "Show more" |
props.theme |
ReverseImageSearchPageTheme
|
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.3.2/static/css/sstk-widget.css">
<script src="https://api-cdn.shutterstock.com/2.3.2/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
Parameter | Type | Description |
---|---|---|
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
Parameter | Type | Description |
---|---|---|
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 |
VideoDetailsPage
Example
const myVideoDetailsPage = {
component: ShutterstockWidget.components.VideoDetailsPage,
name: 'myVideoDetailsPage',
props: {
bindNavigation: false,
showSearchBar: true,
buttons: [
{
label: 'Insert preview',
icon: '/download-comp.svg',
onClick: (e, item) => {
e.preventDefault();
console.log(`Insert code to preview video ${item.id} here.`);
},
},
{
label: 'License',
icon: '/shopping-cart.svg',
onClick: (e, item) => {
e.preventDefault();
const subscriptions = await fetch('YOUR_BACKEND_ROUTE_TO_FETCH_SUBSCRIPTIONS');
widget.navigateTo('myVideoLicensingPage', {
subscriptions,
item,
});
},
},
],
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
myVideoLicensingPage, // Not shown in this example
myVideoDetailsPage,
],
});
widget.render();
A page that shows information about a single video
Parameter | Type | Description |
---|---|---|
component |
String
|
(Required) Set to ShutterstockWidget.components.VideoDetailsPage |
name |
String
|
(Required) A unique name for the page |
props |
Object
|
The configuration properties for the page |
props.bindNavigation |
Boolean
|
Whether to show navigation buttons under the video; these buttons move to the next or previous video from the videos on the previous page, such as a collection page or search results 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 |
VideoResult
|
Information about the video to show on the page |
props.item.id |
Object
|
The ID of an asset to show on the page |
props.searchResults |
[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 |
VideoDetailsPageTheme
|
The CSS classes for the page |
VideoLicenseHistoryPage
Example
const mockVideoLicenseHistory = {
"total_count": 3,
"page": 1,
"per_page": 2,
"data": [
{
id: "e121",
user: {
"username": "myusername"
},
"license": "footage_premier",
"subscription_id": "s8907043",
"download_time": "2018-05-24T14:26:25-04:00",
"metadata": {
"customer_id": "12345",
"geo_location": "US",
"number_viewed": "15",
"search_term": "dog"
},
video: {
id: "2140697",
"format": {
"size": "sd"
}
}
},
{
id: "e122",
user: {
"username": "myusername"
},
"license": "footage_premier",
"subscription_id": "s8907043",
"download_time": "2018-05-24T14:26:25-04:00",
"metadata": {
"customer_id": "12345",
"geo_location": "US",
"number_viewed": "15",
"search_term": "dog"
},
video: {
id: "2140698",
"format": {
"size": "sd"
}
}
},
{
"id": "e123",
"user": {
"username": "myusername"
},
"license": "footage_premier",
"subscription_id": "s8907043",
"download_time": "2018-05-24T14:26:25-04:00",
"metadata": {
"customer_id": "12345",
"geo_location": "US",
"number_viewed": "15",
"search_term": "dog"
},
"video": {
"id": "2140699",
"format": {
"size": "sd"
}
}
}
]
};
const mockNextPageVideoLicenseHistory = {
"total_count": 3,
"page": 2,
"per_page": 20,
"data": [
{
id: "e125",
user: {
"username": "myusername"
},
"license": "footage_premier",
"subscription_id": "s8907043",
"download_time": "2018-05-24T14:26:25-04:00",
"metadata": {
"customer_id": "12345",
"geo_location": "US",
"number_viewed": "15",
"search_term": "dog"
},
"video": {
id: "2140679",
"format": {
"size": "sd"
}
}
},
{
id: "e126",
user: {
"username": "myusername"
},
"license": "footage_premier",
"subscription_id": "s8907043",
"download_time": "2018-05-24T14:26:25-04:00",
"metadata": {
"customer_id": "12345",
"geo_location": "US",
"number_viewed": "15",
"search_term": "dog"
},
video: {
id: "2140689",
"format": {
"size": "sd"
}
}
},
{
"id": "e127",
"user": {
"username": "myusername"
},
"license": "footage_premier",
"subscription_id": "s8907043",
"download_time": "2018-05-24T14:26:25-04:00",
"metadata": {
"customer_id": "12345",
"geo_location": "US",
"number_viewed": "15",
"search_term": "dog"
},
"video": {
"id": "2140611",
"format": {
"size": "sd"
}
}
}
]
};
window.onload = () => {
const attachClickEventListeners = () => {
// Attach click event listener
document.getElementById('video-license-history-page-link').addEventListener('click', async () => {
// Fetch license history from backend.
const licenseHistory = mockVideoLicenseHistory || await fetch('YOUR_BACKEND_ROUTE_TO_FETCH_LICENSE_HISTORY');
widget.navigateTo('myVideoLicenseHistoryPage', {
licenseHistory: licenseHistory,
});
});
};
attachClickEventListeners();
const myVideoLicenseHistoryPage = {
name: 'myVideoLicenseHistoryPage',
component: ShutterstockWidget.components.VideoLicenseHistoryPage,
props: {
onLicenseHistoryItemClick: (item) => {
// Navigate to the video details page (not included in this example)
e.preventDefault();
widget.navigateTo('myVideoDetailsPage', {
item,
});
},
getMoreResults: async (page) => {
// Fetch more results from the server-side code
const nextResults = mockNextPageVideoLicenseHistory || 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: [
myVideoLicenseHistoryPage,
myVieoDetailsPage, //Not included in this example
],
});
widget.render();
}
A page that is intended to show the videos that the user has already licensed, but it can show any list of assets that you pass to its props.LicenseHistory
parameter
Parameter | Type | Description |
---|---|---|
component |
String
|
(Required) Set to ShutterstockWidget.components.VideoLicenseHistoryPage |
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 |
LicenseHistoryPageTheme
|
The CSS classes for the page |
VideoLicensingPage
Example
const myVideoLicensingPage = {
name: 'myVideoLicensingPage',
component: ShutterstockWidget.components.VideoLicensingPage,
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 videos');
},
},
],
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 = mockVideoSubscriptions || await fetch('YOUR_BACKEND_ROUTE_TO_FETCH_SUBSCRIPTIONS');
widget.navigateTo('myVideoLicensingPage', {
subscriptions,
item,
});
},
},
];
const mockVideoSubscriptions = [
{
"id": "s62388302",
"license": "premier",
"description": "Premier Account",
"asset_type": "videos",
"price_per_download": {
"local_amount": 100,
"local_currency": "USD"
},
"allotment": {
"downloads_left": 50000,
"downloads_limit": 50000
},
"formats": [
{
"height": 1080,
"width": 1920,
"fps": 29.97,
"media_type": "video",
"description": "HD MPEG",
"format": "HD",
"min_resolution": 1080,
"size": "hd"
},
{
"height": 480,
"width": 853,
"fps": 29.97,
"media_type": "video",
"description": "Standard Definition MPEG",
"format": "SD",
"min_resolution": 480,
"size": "sd"
},
]
}
];
const mySearchPage = {
name: 'mySearchPage',
component: ShutterstockWidget.components.SearchPage,
props: {
mediaType: 'videos',
onItemClick: (e, item) => {
e.preventDefault();
const subscriptions = mockVideoSubscriptions || await fetch('YOUR_BACKEND_ROUTE_TO_FETCH_SUBSCRIPTIONS');
widget.navigateTo('myVideoLicensingPage', {
subscriptions,
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: [
myVideoLicensingPage,
mySearchPage,
],
});
widget.render();
A page that lets the user select a subscription and license a video asset
Parameter | Type | Description |
---|---|---|
component |
String
|
(Required) Set to ShutterstockWidget.components.VideoLicensingPage |
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 |
[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 |
VideoLicensingPageTheme
|
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
Parameter | Type | Description |
---|---|---|
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();
const subscriptions = await fetch('YOUR_BACKEND_ROUTE_TO_FETCH_SUBSCRIPTIONS');
widget.navigateTo('myImageLicensingPage', {
subscriptions,
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
Parameter | Type | Description |
---|---|---|
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
Parameter | Type | Description |
---|---|---|
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
Parameter | Type | Description |
---|---|---|
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
Parameter | Type | Description |
---|---|---|
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
Parameter | Type | Description |
---|---|---|
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
Breadcrumb
Example
{
label: "Home page",
to: "/",
}
A breadcrumb link to show at the top of the page
Field | Type | Description |
---|---|---|
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
Field | Type | Description |
---|---|---|
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
Field | Type | Description |
---|---|---|
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
Field | Type | Description |
---|---|---|
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
Field | Type | Description |
---|---|---|
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',
},
navigationButtons: {
containerCol: 'containerColCssClass',
containerDiv: 'containerDivCssClass',
previousButton: 'previousButton',
nextButton: 'nextButton',
},
iconClass: 'iconClassCssClass',
ctaLabelClass: 'ctaLabelClassCssClass',
}
Classes for the image details page
Field | Type | Description |
---|---|---|
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 |
navigationButtons |
Object
|
Classes for the navigation buttons below the image |
navigationButtons.containerCol |
String
|
The class for the navigation buttons outer container column |
navigationButtons.containerDiv |
String
|
The class for the navigation buttons inner container div |
navigationButtons.nextButton |
String
|
The class for the next navigation button |
navigationButtons.previousButton |
String
|
The class for the previous navigation button |
ImageLicensingPageTheme
Example
{
breadcrumb: {
breadcrumbContainer: 'breadcrumbContainerCssClass',
link: 'breadcrumbLinkCssClass',
text: 'breadcrumbTextCssClass',
breadcrumbArrow: 'breadcrumbArrowCssClass',
},
iconClass: 'iconClassCssClass',
ctaLabelClass: 'ctaLabelClassCssClass',
}
Classes for the image licensing page
Field | Type | Description |
---|---|---|
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
Field | Type | Description |
---|---|---|
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
Field | Type | Description |
---|---|---|
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
Field | Type | Description |
---|---|---|
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
and GET /v2/videos/licenses
endpoint returns
Field | Type | Description |
---|---|---|
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 |
LicenseHistoryPageTheme
Example
{
container: 'containerCssClass',
imageId: 'imageIdCssClass',
size: 'sizeCssClass',
date: 'dateCssClass',
}
Classes for the license history page
Field | Type | Description |
---|---|---|
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 |
OverlayAction
Example
{
icon: '/icon.svg',
label: 'Hello',
onClick: (e, item) => {
e.preventDefault();
console.log(item);
},
}
Clickable action icon to overlay on search results
Field | Type | Description |
---|---|---|
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
Field | Type | Description |
---|---|---|
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 |
ReverseImageSearchPageTheme
Example
{
pagination: {
container: 'containerCssClass',
showMore: 'showMoreCssClass',
},
}
Classes for the reverse image search page
Field | Type | Description |
---|---|---|
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 |
searchBarDropdownFilter
Example
{
label: 'Vertical mountains',
assetType: 'images',
params: {
query: "mountains",
orientation: "vertical",
},
}
A custom filter for the search bar
Field | Type | Description |
---|---|---|
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
Field | Type | Description |
---|---|---|
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
Field | Type | Description |
---|---|---|
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
Field | Type | Description |
---|---|---|
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 |
VideoDetailsPageTheme
Example
{
container: 'classnameForContainerForVideoPlayer',
breadcrumb: {
breadcrumbContainer: 'breadcrumbContainerCssClass',
link: 'breadcrumbLinkCssClass',
text: 'breadcrumbTextCssClass',
breadcrumbArrow: 'breadcrumbArrowCssClass',
},
iconClass: 'iconClassCssClass',
ctaLabelClass: 'ctaLabelClassCssClass',
navigationButtons: {
containerCol: 'containerColCssClass',
containerDiv: 'containerDivCssClass',
previousButton: 'previousButton',
nextButton: 'nextButton',
},
videoPlayer: {
root: 'classnameRoot',
video: {
container: 'container',
},
controls: {
root: 'controlsRoot',
seek: {
container: 'seekContainer',
track: 'trackerContainer',
buffer: 'bufferContainer',
},
playPause: {
container: 'playPauseContainer',
},
fullscreen: {
container: 'fullscreenContainer',
},
time: {
container: 'timeContainer',
},
rotateButton: {
container: 'rotateButtonContainer',
},
volume: {
container: 'volumeContainer',
},
},
},
}
Classes for the video details page
Field | Type | Description |
---|---|---|
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 |
navigationButtons |
Object
|
Classes for the navigation buttons below the video |
navigationButtons.containerCol |
String
|
The class for the navigation buttons outer container column |
navigationButtons.containerDiv |
String
|
The class for the navigation buttons inner container div |
navigationButtons.nextButton |
String
|
The class for the next navigation button |
navigationButtons.previousButton |
String
|
The class for the previous navigation button |
videoPlayer |
Object
|
Classes for the video player |
videoPlayer.controls |
Object
|
The classes for the buttons on the video player |
videoPlayer.controls.fullscreen.container |
String
|
The class for the container for the full screen button |
videoPlayer.controls.playPause.container |
String
|
The class for the container for the play/pause button |
videoPlayer.controls.root |
String
|
The class for the container for the buttons |
videoPlayer.controls.rotateButton.container |
String
|
The class for the container for the button that rotates the video |
videoPlayer.controls.seek.buffer |
String
|
The class for the part of the timeline that indicates how much of the video has buffered |
videoPlayer.controls.seek.container |
String
|
The classes for the container that includes the timeline |
videoPlayer.controls.seek.track |
String
|
The class for the timeline |
videoPlayer.controls.time.container |
String
|
The class for the container for the length and current position of the video |
videoPlayer.controls.volume.container |
String
|
The class for the container for the volume controls |
videoPlayer.root |
String
|
The class for the container for the video player |
videoPlayer.video.container |
Object
|
The class for the container for the video |
VideoLicensingPageTheme
Example
{
container: 'classnameForContainerForVideoPlayer',
breadcrumb: {
breadcrumbContainer: 'breadcrumbContainerCssClass',
link: 'breadcrumbLinkCssClass',
text: 'breadcrumbTextCssClass',
breadcrumbArrow: 'breadcrumbArrowCssClass',
},
iconClass: 'iconClassCssClass',
ctaLabelClass: 'ctaLabelClassCssClass',
videoPlayer: {
root: 'classnameRoot',
video: {
container: 'container',
},
controls: {
root: 'controlsRoot',
seek: {
container: 'seekContainer',
track: 'trackerContainer',
buffer: 'bufferContainer',
},
playPause: {
container: 'playPauseContainer',
},
fullscreen: {
container: 'fullscreenContainer',
},
time: {
container: 'timeContainer',
},
rotateButton: {
container: 'rotateButtonContainer',
},
volume: {
container: 'volumeContainer',
},
},
},
}
Classes for the video licensing page
Field | Type | Description |
---|---|---|
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 |
videoPlayer |
Object
|
Classes for the video player |
videoPlayer.controls |
Object
|
The classes for the buttons on the video player |
videoPlayer.controls.fullscreen.container |
String
|
The class for the container for the full screen button |
videoPlayer.controls.playPause.container |
String
|
The class for the container for the play/pause button |
videoPlayer.controls.root |
String
|
The class for the container for the buttons |
videoPlayer.controls.rotateButton.container |
String
|
The class for the container for the button that rotates the video |
videoPlayer.controls.seek.buffer |
String
|
The class for the part of the timeline that indicates how much of the video has buffered |
videoPlayer.controls.seek.container |
String
|
The classes for the container that includes the timeline |
videoPlayer.controls.seek.track |
String
|
The class for the timeline |
videoPlayer.controls.time.container |
String
|
The class for the container for the length and current position of the video |
videoPlayer.controls.volume.container |
String
|
The class for the container for the volume controls |
videoPlayer.root |
String
|
The class for the container for the video player |
videoPlayer.video.container |
Object
|
The class for the container for the video |
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
Field | Type | Description |
---|---|---|
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 |