{"id":18711741,"url":"https://github.com/algolia/instantsearch-workshop","last_synced_at":"2025-06-19T15:43:48.030Z","repository":{"id":66050859,"uuid":"71636843","full_name":"algolia/instantsearch-workshop","owner":"algolia","description":"A 10-minute, step-by-step guide to creating your first instantsearch experience.","archived":false,"fork":false,"pushed_at":"2017-11-06T07:36:27.000Z","size":10,"stargazers_count":8,"open_issues_count":0,"forks_count":16,"subscribers_count":70,"default_branch":"master","last_synced_at":"2025-04-25T11:53:18.670Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://community.algolia.com/instantsearch-workshop/","language":"CSS","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/algolia.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2016-10-22T12:12:18.000Z","updated_at":"2019-07-11T13:54:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"a386e2e6-4378-49cb-95c6-931986ed923f","html_url":"https://github.com/algolia/instantsearch-workshop","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/algolia/instantsearch-workshop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/algolia%2Finstantsearch-workshop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/algolia%2Finstantsearch-workshop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/algolia%2Finstantsearch-workshop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/algolia%2Finstantsearch-workshop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/algolia","download_url":"https://codeload.github.com/algolia/instantsearch-workshop/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/algolia%2Finstantsearch-workshop/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260781696,"owners_count":23062285,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T12:40:38.377Z","updated_at":"2025-06-19T15:43:43.020Z","avatar_url":"https://github.com/algolia.png","language":"CSS","funding_links":[],"categories":["CSS","Guides \u0026 Tutorials"],"sub_categories":["Community"],"readme":"# instantsearch workshop\r\n\r\n*(first held at the [Hackference 2016](https://2016.hackference.co.uk) hackathon in Birmingham, UK)*\r\n\r\nAt the end of the workshop you'll have used [instantsearch.js](https://community.algolia.com/instantsearch.js) to create a powerful search page for IMDB data. By default,\r\nit will look like this, giving the user the abilty to search by title and facet by genre and rating:\r\n\r\n![Example search](https://dl.dropboxusercontent.com/s/wgrg39yh5i4akgb/Screenshot%202016-10-22%2013.14.55.png)\r\n\r\n## Setup\r\n\r\nFork this repository. You can also clone it, but if you fork it then you'll have the hassle-free option to deploy to Github pages.\r\n\r\nClone your fork and open the `index.html` page in your editor.\r\n\r\n## Workshop\r\n\r\n### Act 1\r\n\r\nOpen the `index.html` page in your browser. You should see basic HTML and a search box but no results. We're going to add the code step by step to get results to display and then we'll add more interactivity with facets.\r\n\r\nAdd this code to the `search.js` file. This instantiates instantsearch object and configures it with an Algolia `appID`, `apiKey` and `indexName`.\r\n\r\n``` javascript\r\nvar search = instantsearch({\r\n  appId: 'latency',\r\n  apiKey: '6be0576ff61c053d5f9a3225e2a90f76',\r\n  indexName: 'movies',\r\n  urlSync: {}\r\n});\r\n```\r\n\r\nThe Algolia app and index contains data that was uploaded in advance of the workshop. To upload your own data to Algolia, first get a [free account](https://www.algolia.com/users/sign_up), then check out the [import documentation](https://www.algolia.com/doc/guides/indexing/import-synchronize-data) to upload data and configure the index. Then, if you'd like to continue the workshop with your own data, just replace `appId`, `apiKey` and `indexName` with your own values.\r\n\r\nNext, add this code after the last line. This registers the `input` text box as the search box for our application.\r\n\r\n``` javascript\r\nsearch.addWidget(\r\n  instantsearch.widgets.searchBox({\r\n    container: '#q'\r\n  })\r\n);\r\n```\r\n\r\nNext, let's add a widget that will display the results of the search. The `#hits` element is the container that we'll put our results in.\r\n\r\n``` javascript\r\nsearch.addWidget(\r\n  instantsearch.widgets.hits({\r\n    container: '#hits',\r\n    hitsPerPage: 10,\r\n  })\r\n);\r\n```\r\n\r\nAdd this at the end of the file and save it.\r\n\r\n```\r\nsearch.start();\r\n```\r\n\r\nRefresh your browser pointed to `index.html`. You should see now results that will change as you type queries.\r\nThe results will be shown as raw JSON until we template them, so let's template them :)\r\n\r\n### Act 2\r\n\r\nAdd these templates above the hits widget declaration:\r\n\r\n``` javascript\r\nvar hitTemplate =\r\n  '\u003cdiv class=\"hit media\"\u003e' +\r\n    '\u003cdiv class=\"media-left\"\u003e' +\r\n      '\u003cdiv class=\"media-object\" style=\"background-image: url(\\'{{image}}\\');\"\u003e\u003c/div\u003e' +\r\n    '\u003c/div\u003e' +\r\n    '\u003cdiv class=\"media-body\"\u003e' +\r\n      '\u003ch4 class=\"media-heading\"\u003e{{{_highlightResult.title.value}}} {{#stars}}\u003cspan class=\"ais-star-rating--star{{^.}}__empty{{/.}}\"\u003e\u003c/span\u003e{{/stars}}\u003c/h4\u003e' +\r\n      '\u003cp class=\"year\"\u003e{{year}}\u003c/p\u003e\u003cp class=\"genre\"\u003e{{#genre}}\u003cspan class=\"badge\"\u003e{{.}}\u003c/span\u003e {{/genre}}\u003c/p\u003e' +\r\n    '\u003c/div\u003e' +\r\n  '\u003c/div\u003e';\r\n\r\nvar noResultsTemplate =\r\n  '\u003cdiv class=\"text-center\"\u003eNo results found matching \u003cstrong\u003e{{query}}\u003c/strong\u003e.\u003c/div\u003e';\r\n\r\n```\r\n\r\nNext, replace the last `instantsearch.widgets.hits` declaration with this snippet. **Make sure you do not end up with duplicate declarations.**\r\n\r\n``` javascript\r\nsearch.addWidget(\r\n  instantsearch.widgets.hits({\r\n    container: '#hits',\r\n    hitsPerPage: 10,\r\n    templates: {\r\n      empty: noResultsTemplate,\r\n      item: hitTemplate\r\n    },\r\n    transformData: function(hit) {\r\n      hit.stars = [];\r\n      for (var i = 1; i \u003c= 5; ++i) {\r\n        hit.stars.push(i \u003c= hit.rating);\r\n      }\r\n      return hit;\r\n    }\r\n  })\r\n);\r\n\r\n```\r\n\r\nRefresh your `index.html` page, things should be looking much better now.\r\n\r\n### Act 3\r\n\r\nNow let's add a few more widgets. These can go right before the `search.start()` call at the end of the file.\r\n\r\nFirst, for pagination.\r\n\r\n``` javascript\r\nsearch.addWidget(\r\n  instantsearch.widgets.pagination({\r\n    container: '#pagination',\r\n    cssClasses: {\r\n      root: 'pagination',\r\n      active: 'active'\r\n    }\r\n  })\r\n);\r\n```\r\n\r\nNext, to refine by genre.\r\n\r\n``` javascript\r\nsearch.addWidget(\r\n  instantsearch.widgets.refinementList({\r\n    container: '#genres',\r\n    attributeName: 'genre',\r\n    operator: 'and',\r\n    limit: 10,\r\n    cssClasses: {\r\n      list: 'nav nav-list',\r\n      count: 'badge pull-right',\r\n      active: 'active'\r\n    }\r\n  })\r\n);\r\n```\r\n\r\nNext, to use the star rating:\r\n\r\n``` javascript\r\nsearch.addWidget(\r\n  instantsearch.widgets.starRating({\r\n    container: '#ratings',\r\n    attributeName: 'rating',\r\n    cssClasses: {\r\n      list: 'nav',\r\n      count: 'badge pull-right'\r\n    }\r\n  })\r\n);\r\n```\r\n\r\nLastly, to add stats, like the performance of the search.\r\n\r\n``` javascript\r\nsearch.addWidget(\r\n  instantsearch.widgets.stats({\r\n    container: '#stats'\r\n  })\r\n);\r\n```\r\n\r\nSave the `search.js` file and reload `index.html`. Search for a few of your favorite movies. Refine results as you please.\r\n\r\nNote: this example uses an Algolia index that has already been created and populated. You can also use it with an index of your own, just remember to change the `appId` and `apiKey` above and the templates for displaying information. You will also need to configure faceting for each element field you have added a faceting widget for. You can do this on the `Display/Faceting` tab of the index inside of your Algolia dashboard.\r\n\r\n## Host on Github Pages\r\n\r\nJust head to the settings for your fork and flip the Github pages source to `master` branch.\r\n\r\n![Github settings](https://dl.dropboxusercontent.com/s/c3p1wtu1pir5pwn/Screenshot%202016-10-22%2013.20.53.png)\r\n\r\n## Thanks!\r\n\r\nThanks for doing the instantsearch workshop!\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falgolia%2Finstantsearch-workshop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falgolia%2Finstantsearch-workshop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falgolia%2Finstantsearch-workshop/lists"}