Flexsearch

Built-in document search of Next Docs

Next Docs supports searching document based on Flexsearch.

As the bulit-in search of Next Docs, It is the default but also recommended option since it's easier to setup and totally free.

Usage

Note: If you're using a CMS, you should use the API provided by the CMS instead.

Assumes you're using Contentlayer.

  1. Create the API Route.
app/api/search/route.ts
import { allDocs } from 'contentlayer/generated'
import { createSearchAPI } from 'next-docs-zeta/server'
 
export const { GET } = createSearchAPI('simple', {
  indexes: allDocs.map(docs => ({
    title: docs.title,
    content: docs.body.raw,
    url: '/docs/' + docs.slug
  }))
})
  1. Create a Search Dialog.
import { useDocsSearch } from 'next-docs-zeta/search'
 
export function Dialog() {
  const { search, setSearch, query } = useDocsSearch()
  return <div>...</div>
}

createSearchAPI

Create a GET route handler, that supports simple and advanced search.

createI18nSearchAPI

Create a GET route handler with i18n functionality.

Learn how to implement i18n

useDocsSearch

A hook that combined debounce value and useSWR.

Return Type

PropTypeDescription
querySWRResponseSWR Query
searchstringSearching text (not debounced)
setSearch(v: string) => voidSet searching text

Response Data

Type
emptyIf the searching text is empty or blank
SortedResult[]Array of matching pages, headings and contents.

Custom Algorithm

You can port your own search algorithm by returning a list of SortedResult from your custom /api/search/route.ts api endpoint, and you can integrate it with Next Docs UI.

PropTypeDefault
id
string
-
url
string
-
type
enum
-
content
string
-

Currently used by the official documentation, returns a more detailed result with matching headings and contents.

It extracts structured data from a markdown/mdx document, and index it with Flexsearch. With the structure function exported from next-docs-zeta/mdx-plugins.

Known Issues

  • Can't extract content from rehype plugin specific content (you can pass remark plugins)

Usage

Assume you are using Contentlayer with the default configuration.

import { allDocs } from 'contentlayer/generated'
import { createSearchAPI } from 'next-docs-zeta/server'
 
export const { GET } = await createSearchAPI('advanced', {
  indexes: allDocs.map(docs => ({
    id: docs._id,
    title: docs.title,
    content: docs.body.raw,
    url: '/docs/' + docs.slug
 
    // You can preprocess the content with `structure`
    //structuredData: docs.structuredData
  }))
})

Tip:
If you have custom remark plugins enabled, such as remark-math, you have to manually structurize the document with these plugins passed into the function:

import { structure } from 'next-docs-zeta/mdx-plugins'
import remarkMath from 'remark-math'
 
structure(page.body.raw, [remarkMath])

Tag Filter

It's useful for implementing versioned docs, or multi-docs similar to this documentation.

Next Docs UI's Search Dialog doesn't support tag filter.

import { allDocs } from 'contentlayer/generated'
import { experimental_initSearchAPI } from 'next-docs-zeta/server'
 
export const { GET } = await experimental_initSearchAPI(
  allDocs.map(docs => ({
    tag: ...
  })),
  true
)
 
// Pass `tag` in your custom search dialog
const { search, setSearch, query } = useDocsSearch(locale, tag)

Last updated on