Sorry, no results found for "".
In addition to the low-level API request presented in the previous section, our vue-datocms
package also includes a Vue composable ready for rendering a full-featured Site Search widget on your website.
First of all, install the required npm packages in your Vue project:
You can then use the useSiteSearch
composable like this:
1import { useSiteSearch } from 'vue-datocms';2import { buildClient } from '@datocms/cma-client-browser';3
4const client = buildClient({ apiToken: 'YOUR_API_TOKEN' });5
6const { state, error, data } = useSiteSearch({7 client,8 buildTriggerId: '7497',9 // optional: by default fuzzy-search is not active10 fuzzySearch: true,11 // optional: you can omit it if you only have one locale, or you want to find results in every locale12 initialState: { locale: 'en' },13 // optional: defaults to 8 search results per page14 resultsPerPage: 10,15})
Please follow the vue-datocms
documentation to read more about at the configuration options and the data returned by the hook.
The following example shows a search page, including a very simple home-made pagination. You can build more advanced pagination widgets using the data.totalPages
property to get the total number of pages, state.page
to get the current page, and state.page = pageNumber
to trigger a page change.
1<script setup lang="ts">2
3import { useSiteSearch } from 'vue-datocms'4
5import { buildClient } from '@datocms/cma-client-browser';6
7const client = buildClient({ apiToken: 'YOUR_API_TOKEN' });8
9const { state, error, data } = useSiteSearch({10 client,11 buildTriggerId: '7497',12 // optional: by default fuzzy-search is not active13 fuzzySearch: true,14 // optional: you can omit it you only have one locale, or you want to find results in every locale15 initialState: { locale: 'en' },16 // optional: defaults to 8 search results per page17 resultsPerPage: 9,18})19
20</script>21
22<template>23 <div>24 <div class="bg-slate-200 py-4">25 <div class="container mx-auto">26 <input class="py-3 px-5 block w-full border-gray-200 rounded-full text-sm focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400" type="text" v-model="state.query" placeholder="Search: try something like "vue" or "dato"... " />27 </div>28 </div>29 <div class="bg-slate-100 py-4">30 <div class="container mx-auto py-4">31 <h1>{{ data.totalResults}} results</h1>32 </div>33 <div class="container mx-auto py-4 grid grid-cols-3 gap-4" v-if="data">34 <div v-for="result in data.pageResults" class="py-4">35 <div class="py-1">36 <a :href="result.url">37 <strong v-if="result.titleHighlights.length > 0">38 <template v-for="highlight in result.titleHighlights" class="py-1">39 <template v-for="piece in highlight">40 <mark v-if="piece.isMatch">{{ piece.text }}</mark>41 <template v-else>{{ piece.text }}</template>42 </template>43 </template>44 </strong>45 <strong v-else>{{ result.title }}</strong>46 </a>47 </div>48 <div v-for="highlight in result.bodyHighlights" class="py-1">49 <template v-for="piece in highlight">50 <mark v-if="piece.isMatch">{{ piece.text }}</mark>51 <template v-else>{{ piece.text }}</template>52 </template>53 </div>54 <details>55 <summary>Raw results</summary>56 <pre><code class="block whitespace-pre overflow-x-scroll">{{ JSON.stringify(result.raw, null, 2) }}</code></pre>57 </details>58 </div>59 </div>60 <div class="container mx-auto py-4">61 <div class="flex">62 <button v-if="state.page > 0" @click="state.page = state.page - 1" class="flex items-center px-4 py-2 mx-1 text-gray-700 transition-colors duration-300 transform bg-white rounded-md dark:bg-gray-800 dark:text-gray-200 hover:bg-blue-600 dark:hover:bg-blue-500 hover:text-white dark:hover:text-gray-200">63 Previous64 </button>65 <button v-if="state.page < data.totalPages" @click="state.page = state.page + 1" class="flex items-center px-4 py-2 mx-1 text-gray-700 transition-colors duration-300 transform bg-white rounded-md dark:bg-gray-800 dark:text-gray-200 hover:bg-blue-600 dark:hover:bg-blue-500 hover:text-white dark:hover:text-gray-200">66 Next67 </button>68 </div>69 </div>70 </div>71 </div>72</template>