Search
Search as fast as you publish.
Every collection is indexed as you save, ranked and forgiving of typos. Your servers and agents search through the API, your site's visitors as they type, and your team with ⌘K (Ctrl+K on Windows) in the editor.
An example: searching for “refund” across a project returns ranked articles, FAQs and policies, with the matching words highlighted.
- articles
How refunds work
A refund goes back to the original payment method.
- faqs
Can I get a refund after 30 days?
After 30 days, a refund is at our discretion.
- policies
Refunds for annual plans
Annual plans are refunded for the unused months.
- policies
Refunds and agency seats
Unused agency seats are refunded at renewal.
- docs
Tracking a refund
See where each refund is, from requested to paid.
Public search
Search as visitors type. No API in between.
A read-only search token goes in your page source and queries the search engine directly, so results keep pace with typing.
import instantsearch from "instantsearch.js" import { searchBox, hits } from "instantsearch.js/es/widgets" import { instantMeiliSearch } from "@meilisearch/instant-meilisearch" const { searchClient } = instantMeiliSearch( "https://search.nohead.io", token ) instantsearch({ indexName: index, searchClient }) .addWidgets([ searchBox({ container: "#search" }), hits({ container: "#hits", templates: { item: (hit, { html }) => html`${hit.data.title}`, }, }), ]) .start()
const response = await fetch("https://search.nohead.io/multi-search", { method: "POST", headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, body: JSON.stringify({ queries: [{ indexUid: index, q: "lentil soup", limit: 10 }], }), }) const { results } = await response.json() for (const hit of results[0].hits) console.log(hit.data.title)
Published records only
A token finds the published records of the collections you include, and nothing else, whatever a request asks for: the search engine enforces it. Including or removing a collection reaches every token within seconds.
Meilisearch underneath
Public search speaks Meilisearch's own API, so its clients and InstantSearch work as they are, filter lists with counts included. Hits look like records: the ID, the timestamps and the field values under data.
A token per site
Make one for each site or app. Delete one and only that site stops searching, at once; the others keep working. Tokens are public by design: they go in your page source.
Not metered
Searches with a token go straight to the search engine and don't count toward your API requests. Each visitor's address is rate limited, generously enough for search as you type.
API search
For servers and agents. Full records, ranked.
Search with an API key and get back the records the API lists, with filters, sorting and related records, from an SDK, the CLI or plain HTTP.
const recipes = nohead.records.search("recipes", "lentil soup", { filter: { cuisine: "french", published_at: { exists: true } }, sort: "-published_at", expand: ["author"], }) for await (const recipe of recipes) { console.log(recipe.data.title) } // Every collection at once, in one ranked list const results = await nohead.search("lovelace", { collections: ["posts", "authors"], })
for recipe in nohead.records.search( "recipes", "lentil soup", filter={ "cuisine": "french", "published_at": {"exists": True}, }, sort="-published_at", expand=["author"], ): print(recipe.data["title"]) # Every collection at once, in one ranked list results = nohead.search( "lovelace", collections=["posts", "authors"] )
recipes = nohead.records.search( "recipes", "lentil soup", filter: { cuisine: "french", published_at: { exists: true } }, sort: "-published_at", expand: ["author"] ) recipes.each { |recipe| puts recipe.data["title"] } # Every collection at once, in one ranked list results = nohead.search("lovelace", collections: %w[posts authors])
# One collection, filtered and sorted $ nohead search "lentil soup" --collection recipes \ --filter cuisine=french --sort=-published_at # The whole project $ nohead search lovelace --json
- One collection or all of them, in a single ranked list
- Filters and sorts on the fields you mark, with the records list's operators
- Related records embedded with
expand, as in any list - Published-only keys find published records, whatever they ask for
- Current within seconds of every change, with no index to keep in sync yourself
- Cursor pagination through the first 1,000 hits, as in any list
Search settings
Your schema decides what's searched.
Mark each field searchable, filterable or sortable. The same settings apply to every search: in the editor, with an API key and on your site.
Searchable from the start. Text, long text, rich text and enum fields.
Public with one switch. Include a collection in public search; leave private ones out.
Or in a file. The same settings in nohead.schema.yaml, pushed with the CLI.
Index status at a glance. With a rebuild you'll rarely need.
Fast for visitors.
Safe for your data.
Search is a copy of your content, built for speed. The database stays the source of truth, and tokens can only search.
Tokens with one job. The search URL lets searches through and nothing else, and limits how many one address can make.
Never the source of truth. Indexes are built from the database and can be rebuilt at any time. If search is down, reading records works as usual.
Schema changes, handled. Make a field searchable, filterable or sortable and the index rebuilds on its own, while search keeps working.
nohead.schema.yaml. Then search one collection or the whole project from the API, the CLI (nohead search) or the SDKs, ranked by relevance and current within seconds of a change. For search as visitors type, turn on public search: the browser queries the search engine directly with a read-only token, sees published records only, and doesn't count toward your API requests.fetch. Hits look like records, with field values under data, so the components that render your records can render results too. The public search guide has the details.data. Indexes are built from the database and can be rebuilt at any time.Search your first collection.
Create a collection from a template, add a few records and press ⌘K (Ctrl+K on Windows). Then make a search token and search it from your site.