Skip to main content
Version: Stable (v5.x)

Core package

@docsearch/core provides the React state shared by DocSearch views. It owns open and close state, keyboard events, theme selection, lifecycle callbacks, initial queries, and imperative controls. It doesn't render a search interface by itself.

v5 beta

These instructions use the ^5 range.

Install

npm install @docsearch/core@^5

Packages such as @docsearch/modal and @docsearch/sidepanel consume this provider. For component composition instructions, see the Composable API guide.

Configure shared behavior

SearchState.tsx
import { DocSearch } from '@docsearch/core';

export function SearchState({ children }: { children: React.ReactNode }) {
return (
<DocSearch
theme="dark"
initialQuery="authentication"
keyboardShortcuts={{
'Ctrl/Cmd+K': true,
'/': false,
'Ctrl/Cmd+I': true,
}}
onReady={() => track('docsearch_ready')}
onOpen={() => track('search_opened')}
onClose={() => track('search_closed')}
onSidepanelOpen={() => track('assistant_opened')}
onSidepanelClose={() => track('assistant_closed')}
>
{children}
</DocSearch>
);
}

The default shortcuts enable Control/Command+K, /, and Control/Command+I. Slash doesn't open the modal while focus is in an input, select, textarea, or editable element.

Use a ref

SearchState.tsx
import { DocSearch, type DocSearchRef } from '@docsearch/core';
import { useRef } from 'react';

export function SearchState({ children }: { children: React.ReactNode }) {
const ref = useRef<DocSearchRef>(null);

return (
<>
<button type="button" onClick={() => ref.current?.open()}>
Open search
</button>
<DocSearch ref={ref}>{children}</DocSearch>
</>
);
}

The ref can open and close registered views and report their state. See the core API reference. For interactions between views, see Hybrid Mode.

Read provider state

Call useDocSearch only beneath DocSearch. The hook throws outside the provider.

SearchStatus.tsx
import { useDocSearch } from '@docsearch/core';

export function SearchStatus() {
const { docsearchState, openModal, closeModal } = useDocSearch();

return (
<button
type="button"
onClick={docsearchState === 'ready' ? openModal : closeModal}
>
{docsearchState === 'ready' ? 'Open search' : 'Close search'}
</button>
);
}

Use the higher-level modal and Sidepanel packages for their standard triggers. Read context directly when your interface needs custom controls.