Instant Answer Display Reference
The Instant Answer framework gives you many options for displaying your results in the DuckDuckGo AnswerBar. Below is a detailed reference of the properties and usage of each.
Each Instant Answer has its own ways of declaring these options. We strongly recommend starting with the appropriate usage section, depending on your Instant Answer type:
These sections explain how to display each Instant Answer, as well as code samples involving the options in this reference.
Display Properties
Each Instant Answer is added to the AnswerBar by passing a set of properties to the Instant Answer Framework.
The following properties are required:
- id - A unique identifier for your Spice. The
idshould match the name of your callback function - name - The name that will be used for your Spice's AnswerBar tab
- data - The object containing the data to be used by your templates
- meta - Used to define elements of the MetaBar including the "More at" link
- templates - Used to specify the template group and all other templates that are being used
The following properties are optional:
- normalize - This allows you to normalize the
databefore it is passed on to the template - relevancy - Used to ensure the relevancy of your Spice's result
- sort_fields
- view - This allows you to explicitly specify the view class used for displaying the Instant Answer
- model - This allows you to use one of our predefined data models that include domain specific helpers/normalization/formatting.
- You may also optionally handle several of the AnswerBar's frontend events.
id string [required]
A unique identifier for your Instant Answer.
Notes for Spice Instant Answers
The id should match the name of your callback function. For example, if your callback function is named ddg_spice_name, your id should be spice_name.
name string [required]
The name that will be used in the tab above the Instant Answer, in the AnswerBar.
Tab names should ideally be one word nouns (Images, Videos, Products, Audio, Answer, News, etc.) that describe the type of content being shown.
We will not accept brand names for tabs. Instead, it's best to use the general topic name. For example, 'videos' for YouTube, 'gaming' for Twitch, 'products' for Amazon, and so on.
If none of the topics below apply to your results, or need help, we recommend choosing "Answer" for the time being, and contacting us to brainstorm.
To get an idea for choosing a good name, here are some examples:
| Spice IA | `name` |
|---|---|
| GitHub | 'Software' |
| Last.fm | 'Music' |
| HackerNews | 'News' |
| 'Social' | |
| Amazon | 'Products' |
Ideally your Instant Answer name should be one of the existing topics:
- Answer
- Apps
- Audio
- Computing
- Cryptography
- Currency
- Dictionary
- Domain
- Entertainment
- Finance
- Food & drink
- Games
- Geek
- Geography
- Health
- Images
- Jobs
- Literature
- Local
- Math
- Movies
- Music
- News
- Politics
- Productivity
- Products
- Programming
- Recipes
- Reference
- Science
- Social
- Software
- Special interest
- Sports
- Statistics
- Sysadmin
- Tools
- Travel
- Tv
- Videos
- Weather
- Web design
- Words & games
data object [required]
The object containing the data to be used by your templates. In most cases, it is best to pass along api_result to data, so that all of your API response is accessible to your templates.
meta object [required]
The following options are used to define elements of the MetaBar including the "More at" link.


The following are all properties of the meta: {} object.
sourceNamestring [required for Spice, optional for Goodie]The name of the source as it should be shown in the "More at" link. For example, in "More at Quixey", "Quixey" is specified as
sourceName.Notes for Goodie Instant Answers
While Goodies don't, by definition, have external data sources, you may still decide to specify
sourceNameandsourceUrl(below). For example, the BPM to ms instant answer (search for "120 bpm to ms") specifies Wikipedia as the source, and links to an article that explains the calculation performed by the Goodie.For the best experience, if a relevant Wikipedia page, or authoritative explanation, exists for your Goodie, you should provide it as a
sourceNameandsourceUrl.sourceUrlurl string [required for Spice, optional for Goodie]The URL to follow when the "More at" link is clicked. This value is the
hrefattribute of the "More at" link. This can refer to the main page of the source, or better yet, the specific page relevant to the user's query.A secure https:// connection should be used whenever possible.
Examples
- In rand_word.js, the
sourceUrlis a hardcoded address. - In is_it_up.js, the
sourceUrlis dynamically generated to direct to a specific page relating to the search query.
- In rand_word.js, the
searchTermstring [optional]Determines the modifier in the MetaBar's description: "Showing 15
itemTypeforsearchTerm".The
searchTermis used to describe theitemTypeand it can be determined by removing any skip words from the original query.For example, searching "alternatives to emacs", will display the description "Showing 12 Alternatives for GNU Emacs" in the MetaBar. In this case, the phrase "GNU Emacs" is the
searchTerm.
If no
searchTermis specified, the description will simply read "Showing 12 Movies" or, if noitemTypespecified, "Showing 12 Items".Examples
- In news.js,
searchTermis passed the search query after some basic cleanup. - In images.js,
searchTermis passed the original query as-is. - In alternative_to.js,
searchTermis passed a name provided by the API. - In songkick_geteventid.js,
searchTermis passed a city name.
- In news.js,
itemTypestring [optional]Determines the noun in the MetaBar's description: "Showing 15
itemTypeforsearchTerm". In other words,itemTypeis the type of item being shown (e.g., Videos, Images, Recipes).Searching for "alternatives to emacs", "Showing 12 Alternatives for GNU Emacs", the word "Alternatives" is the
itemType.If no
itemTypeis specified, the default itemType is 'Items'. For example, the MetaBar description will read "Showing 12 Items", or "Showing 12 Items for Electronics" when asearchTermis provided.Examples
- In news.js, the
itemTypeis'News articles'. - In alternative_to.js, the itemType is
'Alternatives'.
- In news.js, the
primaryTextstring [optional]If defined, this text will replace the MetaBar's "Showing n Items" text.
Example
- In parking.js, the
primaryTextis set to'Parking near'plus the location.
- In parking.js, the
secondaryTextstring [optional]This is an optional text label, displayed to the left of the "More at" link. For example, a weather forecast Instant Answer might use this to indicate the temperature unit, such as "Temperature in F°".
sourceLogourl string [optional]If defined, the image provided will replace the
sourceNamewith a logo. Generally this is not necessary; in rare cases, API providers require that a specific image be used to represent their brand.Example
From quixey.js:
meta:{ ... sourceLogo: { url: DDG.get_asset_path('quixey','quixey_logo.png'), width: '45', height: '12' } }This is the result:

sourceIconboolean [optional]A boolean flag that determines if a favicon should be shown to the left of the "More at" link. The favicon is determined automatically by DuckDuckGo based on the
sourceUrl.When a
sourceUrlis given, this will default totrue. It should only be set tofalsewhen thesourceUrldomain does not have a favicon.sourceIconUrlurl string [optional]If the
sourceUrldomain has no favicon (or if a different favicon is preferred), you can explicitly set a url path for the favicon shown to the left of the "More at" link. This value, if set, will take precedence any favicons pulled from thesourceUrldomain.snippetCharsinteger [optional]For blocks of text that require truncation,
snippetCharsallows you to specify the maximum number of characters before truncation (to whole words with ellipses). This applies mainly todescriptionelements in templates.This property is expected to be used in rare cases. Each template comes with its own optimal, default
snippetCharsvalue.pinIconstring [optional]Specifies the class of the built-in icon to use as the map pin. If you are using the Places Template Group, which displays an interactive map, use this to specify which built-in icon you'd like used to mark locations.
This takes a CSS class name of the built-in icon to use. You can find the icons listed in the style guide. For example:
meta: { ... pinIcon: 'ddgsi-circle', pinIconSelected: 'ddgsi-star' }pinIconSelectedstring [optional]Same as
pinIcon, but for selected pins. When focusing on a particular location, use this icon to highlight the corresponding pin on the map.
templates object [required]
A templates: {} property should be used to specify the template group, and/or other templates that are being used.
Template options can also be provided to enable or disable features depending on the chosen template group.
More about how templates work can be found in the Template Overview.
*Note for Goodie Instant Answers: Several properties below allow you to specify a function datatype, in order to reference a custom handlebars template. However, if you intend to do this in a Goodie Perl file, you must pass the name as a string in order to work.*
groupstring [required, unlessitemanddetailare specified]Setting the
groupproperty specifies a preset group of default templates and options (for example,item,detail,optionsetc.). These presets can be customized and manually overridden. The template groups available are described in the Template Groups Overview.For example,
group: 'info'will implicitly set:templates:{ item: 'basic_item', item_detail: 'basic_info_item_detail', detail: 'basic_info_detail' }itemstring (template name) or function (template reference) [required if nogroupis specified]The template to be used for each item in a tile view.
Note: The
itemtemplate is only used when your Instant Answer returns multiple items (like the recipe or BPM to ms Instant Answers). This means the object passed todatais an array with more than one element.Generally, a string is provided to indicate the name of the built-in template to be used, e.g., "products_item"
In rare cases, where necessary, a function referencing a custom template can be passed. Passing a custom template is a measure of last resort due to maintenance difficulty. Learn more about picking templates; if you feel that no current templates fit your idea, please contact us at [email protected] and we'll happily help you find a solution.
item_mobilestring (template name) or function (template reference) [optional]An alternative
itemtemplate to be used when displaying on smaller screens, such as mobile and hand-held devices.detailstring (template name) or function (template reference) [required if nogroupis specified]The template to be used for the detail area. Find out more about when the
detailtemplate is displayed in the templates overviewIf your Instant Answer only returns a single item, a `detail` template is **required**. If your Instant Answer usually returns multiple items, the `detail` template is **optional**.detail_mobilestring (template name) or function (template reference) [optional]An alternative
detailtemplate to be used when displaying on smaller screens, such as mobile and hand-held devices.item_detailstring (template name) or function (template reference) [optional]An alternative
detailtemplate to be used when a tile is clicked. Learn more about whenitem_detailis used in the templates overview.optionsobject [optional]Allows you to explicitly disable or enable the available features of your template using boolean values or by specifying sub-templates to include.
For example, you might set the the
contentfeature of thebasic_info_detailtemplate to a particular sub-template, and enable therowHighlightfeature.For example:
templates: { group: 'info', options: { content: 'record', rowHighlight: true } }Available features will vary with each chosen template (see the templates reference for details on each template). For example, the
basic_info_detailtemplate doesn't have abrandfeature, so settingbrand: trueorbrand: falsewill have no effect.It's important to note that there are implicit default options which apply in the absence of an
optionsobject or a templatesgroup.moreTextstring or object or array [optional]Display additional text or link content adjacent to the 'More at' link. Note that
moreTextis nested under theoptionsproperty.For text alone, pass a string:
templates: { ... options: { moreText: "Movie showtimes are shown in PST time zone" } }To display a link, pass an object:
templates: { ... options: { moreText: { text: "See a 10-day surf forecast" href: "https://..." // Use SSL when possible } } }To display multiple values (either text or links), pass an array:
templates: { ... options: { moreText: [ { text: "See a 10-day surf forecast" href: "https://..." // Use SSL when possible }, { text: "Global Swell Chart" href: "https://..." }, "Subject to local conditions" ] } }Multiple values will be separated by a '|' and display as follows:
More at Surfline | See a 10-day surf forecast | Global Swell Chart | Subject to local conditions
variantsobject [optional]If you'd like to modify a template's visual appearance to fit your needs, the Instant Answer framework offers preset options called Variants. Variants are passed as the
variantsproperty oftemplates.Variants correspond to pre-determined css classes (or combinations of classes) from the DDG style guide that work particularly well in each context.
For more on the options and usage of
variants, visit the templates reference.elClassobject [optional]When variants don't suffice in customizing your templates' appearance, you may directly specify classes from the DDG style guide through the
elClassproperty oftemplates. This feature is mainly used for specifying text size and color.These custom classes can be directly specified on the same template features available to Variants; the locations are identical. If you are specifying both
variantsandelClass, both will be applied together.For more on the options and usage of
elClass, visit the templates reference.
normalize function [optional]
Specifying this optional function allows you to normalize each item in the data object before it is used by the template. You can use this function to rename properties, add new properties, or modify values.
This function is applied both for single results or multiple results. When dealing with multiple items returned in the data object, the normalize function iterates over each item. Each item is individually normalized and passed to its own instance of the item template.
Notes for Goodie Instant Answers
Because Goodies have no external sources and run on the server, a normalize function is not completely necessary to normalize data for templates. However, it is possible (and conceivable) to use a normalize function in a Goodie Instant Answer.
Defining a normalize function in a Goodie, must be done in the frontend part of the code, as JavaScript. For more information about Goodie JavaScript visit the Goodie Display section.
Usage
The function set for normalize is expected to return an object with the properties to be rendered for each item.
The object returned by the normalize function is combined with the original respective item from data.
The normalize function will extend the original data item instead of replacing it. (This uses jQuery's $.extend() method, shallow copy.) Each normalized item will contain its original properties unless they were explicitly overwritten in the normalize function.
Use with Built-In Templates
Normalize can be particularly useful if you are using a built-in template (for example, basic_image_item).
Built-in templates expect that certain properties will be present (such as title and image). The normalize function allows you to provide those (or normalize their values if the property already existed in your data).
For example, if you have a data object that looks like this:
// original data object from API
{
heading: "My awesome title",
image: "http://website.com/image.png"
}
You will likely want to pass the heading property as the title for the basic_image_item template, so your normalize function would need to look like this:
normalize: function(item){
return {
title: item.heading
};
}
This would result in your data object looking like this once it gets passed along to the template:
// normalized data object
{
heading: "My awesome title",
image: "http://website.com/image.png",
title: "My awesome title"
}
Now, your object has all the required properties for the basic_image_item template and everything will be displayed as expected.
Important Note on Enabling Features
If you intend to use a template feature that is disabled by default or disabled by a template group defaults, that feature must be enabled in the options to display.
Even if the property exists in the data object, the template system will ignore it if the feature is disabled.
In this example:
normalize: function(item){
return {
// these won't work!
rating: item.customerRating,
brand: item.brandname
};
},
templates: {
group: 'products_simple'
}
The template will not display the rating or brand as they are disabled by default in the products_simple group default options. Only once they are explicitly enabled in an options object will they work:
normalize: function(item){
return {
// now they'll show, because they're enabled below
rating: item.customerRating,
brand: item.brandname
};
},
templates: {
group: 'products_simple',
options: {
rating: true,
brand: true
}
}
exactMatch boolean and boost boolean
Two special properties, exactMatch and boost, can also be set in the normalize function to add particular items to the list of exact matches or boosted items.
When the tile view displays, the exact match items will come first, followed by the boosted items and then the rest of the items.
Example:
normalize: function(item) {
if (item.name === DDG.get_query()){
item.exactMatch = true;
} else if (item.developer.name === DDG.get_query()) {
item.boost = true;
}
return { ... }
}
relevancy object [optional]
When dealing with multiple items, the relevancy property can be used to ensure the relevancy of each individual item. It can also be used to de-duplicate the returned items if desired.
In most cases you will only need to specify relevancy properties for the primary relevancy block. However, if your Instant Answer is capable of dealing with different types of queries though, where different relevancy checks are necessary, you can supply additional relevancy blocks.
For example, the Quixey Spice (app search) handles two distinct types of app searches:
- Categorical searches, such as "social networking apps"
- Named searches such as "free angry birds apps"
When dealing with categorical searches, the name of the app doesn't need to be checked against the query for relevancy. However, the app's category does need to be checked and so two separate relevancy blocks, primary and category, are used to define the different relevancy constraints.
Sample code from quixey.js:
relevancy: {
...
category: [
{ required: 'icon_url' },
{ key: 'short_desc' },
{ key: 'name' },
{ key: 'custom.features.category', match: category_match_regexp, strict:false } // strict means this key has to contain a category phrase or we reject
],
primary: [
{ required: 'icon_url' }, // would like to add alt: 'platforms.0.icon_url'
{ key: 'name', strict: false },
]
}
Notes for Goodie Instant Answers
The relevancy property is unlikely to be used in a Goodie Instant Answer, although it is completely functional. Potential use in a Goodie might involve large data sets to search through.
If using relevancy in a Goodie, it must be specified in the frontend part of the code, as JavaScript. For more information about Goodie JavaScript visit the Goodie Display section.
Relevancy Blocks
A relevancy block is comprised of an array of simple objects. For each object, the properties are used to indicate certain constraints. The concept of a relevancy block is best explained with an example:
// First we provide the name for the relevancy block, "primary"
primary: [
{ required: 'icon_url' },
// "required" means the item must have a defined property matching the
// given name, in this case and "icon_url" must be defined for each Quixey
// item
//
// Note: "required" only ensures the presence of a property. It does NOT
// perform a relevancy check
{ key: 'name', strict: true },
// "key" indicates a property which will be checked for relevancy. If
// the given key is determined to be relevant, the item as a whole is
// considered relevant and no other keys in the relevancy block are
// checked for the current item
//
// The "strict" key allows you to turn on the "strict mode"
// for DDG.isRelevant
{ key: 'short_desc' }
// this is an extra "key" which serves as a fallback. This means if
// either the 'name' or 'short_desc' or relevant the item is considered
// relevant
],
// here we provide a secondary relevancy block with a chosen name of "category"
category: [
{ required: 'icon_url' },
{ key: 'name' },
{ key: 'short_desc' },
{ key: 'custom.features.category', match: category_regexp }
// the "match" key allows you to specify a regular expression which the
// given "key" must match
//
// Note: "match" only ensures the property matches the given regex. It
// does NOT perform a relevancy check
],
Note: The relevancy checking is done using the DDG.isRelevant() function.
typestringThe name of the relevancy block to use. If no value is provided, the default
primaryblock will be used.For example, the Quixey spice determines the
typebased on the query. If the query matches against our category regex (i.e. the query contains a category word), we settypeto "category", otherwise we use "primary".skip_wordsarrayA list of words to skip when comparing the specified text against the current query. Generally these words should include any trigger words for your Instant Answer. The skip words list is not dependent on the chosen relevancy block.
primaryarray [required if usingrelevancy]The list of relevancy terms for this particular relevancy block
<additional_relevancy_block>arrayAn additional list of relevancy terms, using the same format as
primary. This object (and other relevancy blocks) can be named arbitrarily.dupstringThis indicates which property should be used to check for de-duplication. The given string supports dot path formatting, e.g., "item.foo.bar"
sort_fields object [optional]
In some cases, the order of the tiles is important (e.g., price, rating, popularity) and you can use the sorting properties to specify the default ordering of the tiles. You can also specify additional sorting fields that will allow users to re-order the tiles using a different sort method.
This object specifies sorting fields (e.g., name, price, rating, reviews) and their respective comparison functions, which will be passed along to JavaScript's sort() method.
Example:
sort_fields: {
name: function(a,b) {
return a.name < b.name ? -1 : 1;
},
rating: function(a,b) {
return a.rating < b.rating ? -1 : 1;
}
}
Notes for Goodie Instant Answers
When setting sort_fields properties in a Goodie, you must specify them in the frontend part of the code, as javascript. For more information about Goodie javascript visit the Goodie Display section.
sort_default string or object
A string specifying the default sort_field to be used for initial sorting of the tiles.
sort_default: 'name';
If you have used more than one relevancy block, sort_default can be given an object specifying the default sort_field for each relevancy block.
For example, if we had two relevancy blocks named primary and category our default_sort could look like this:
//because we have two relevancy blocks...
sort_default: {
primary: 'name',
category: 'rating'
}
view string [optional]
Typically you don't need to specify a view for Instant Answers unless you're using special functionality like the playable Audio tiles for the SoundCloud IA, or the Maps used in our Places IA.
Available Views:
- Audio
- Detail (default view for IAs with a single item)
- Images
- Map
- Places
- Tiles (default view for IAs with multiple items)
- TilesWithTopics
- Videos
model string [optional]
Some Instant Answers use data to display results which is not directly displayed in a template. For example, the latitude and longitude of a Place, or the dimensions of an Image. The Instant Answer framework comes with built-in models to manage these data. Some views require a model - such as Audio or Places.
If you are specifying a template group, the model property is automatically set for you.
Available models:
- Audio
- Image
- Place
- Product
- Video
More about using models and their properties can be found in their respective template groups.
Events
If you need to fire off an event handler when a tile is clicked or when your Instant Answer's tab initially opens, you can handle these events with a callback function.
onItemSelectedfunctionThis event occurs each time a tile is selected with a click.
Example:
onItemSelect: function(item) { player.play(item); }Learn more about the
itemargument below.Note: If a tile-view result returns a single result, this event will also fire when the tab is opened/clicked, so you don't need to use both
onItemSelectedandonShowto handle the case of a single-result tile viewonItemUnselectfunctionThis event occurs each time a tile is unselected - i.e., the user clicks somewhere else on the page.
onItemUnselect: function(item) { // Pause playing media, change appearance, etc. }Learn more about the
itemargument below.Note: If a tile-view result returns a single result, this event will also fire when the tab is closed, so you don't need to use both
onItemSelectedandonShowto handle the case of a single-result tile viewonShowfunctionThis event occurs each time an Instant Answer tab is displayed. This event fires when the Instant Answer is initially shown. It also fires when a user clicks another AnswerBar tab, then clicks to show it again.
onItemShownfunctionSame behavior as
onShow, but fired on a per-item basis. This is useful for separately requesting and updating information relevant to each tile - e.g. secondary API calls. For example, the Amazon Spice uses this event to render product ratings, and the Movie Spice sets each tile's image element using this event.onItemShown: function(item) { // Do something to the item, such as update latest info }Learn more about the
itemargument below.onHidefunctionThis event occurs when a Instant Answer tab is closed i.e. when another tab is selected.
The item Argument
Events relevant to specific items pass an item to their handler functions. This is a reference to the item's data object, rendered to the template. Modifying the properties will not update the DOM.
An added item.$html property references the respective item DOM element as a jQuery object.
Notes for Goodie Instant Answers
When creating a Goodie, you must declare event handlers in the frontend part of the code, as JavaScript. For more information about Goodie JavaScript visit the Goodie Display section.