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

React Sidepanel advanced use cases

Push page content

Use the inline panel variant to add a margin to the first element that matches pushSelector. On screens up to 768 pixels wide, the panel overlays the page instead.

Docs.tsx
<SidepanelButton variant="inline" />
<Sidepanel
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
assistantId="YOUR_AGENT_ID"
indexName="YOUR_INDEX_NAME"
variant="inline"
side="left"
pushSelector="#documentation"
width="24rem"
expandedWidth="36rem"
/>

Keep pushSelector narrow enough to identify one layout container. The implementation uses the first matching element and restores its inline margin and transition when it unmounts.

Render into another container

Both the floating button and panel default to document.body. Set portalContainer on the panel and portalcontainer on the button to use another element. The button prop is lower-case in the v5 beta API.

AssistantPortal.tsx
const assistantRoot = document.getElementById('assistant-root');

<DocSearch>
<SidepanelButton portalcontainer={assistantRoot} />
<Sidepanel
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
assistantId="YOUR_AGENT_ID"
indexName="YOUR_INDEX_NAME"
portalContainer={assistantRoot}
/>
</DocSearch>;

An inline SidepanelButton renders where it appears in the React tree and doesn't use its portal container.

Control the panel with a ref

Attach a DocSearchRef to the provider. openSidepanel accepts an optional initial message.

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

export function Support() {
const docsearchRef = useRef<DocSearchRef>(null);

return (
<DocSearch ref={docsearchRef}>
<button
type="button"
onClick={() =>
docsearchRef.current?.openSidepanel({
query: 'How do I rotate an API key?',
})
}
>
Ask about API keys
</button>
<Sidepanel
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
assistantId="YOUR_AGENT_ID"
indexName="YOUR_INDEX_NAME"
/>
</DocSearch>
);
}

Call the method after the Sidepanel has mounted and registered its view. Check isSidepanelOpen to read its open state. See Hybrid Mode for cross-view ref behavior.

Handle Agent Studio tools

Key each client tool by the name emitted by your agent. Always return tool output through addToolOutput when you provide onToolCall.

tools.tsx
const tools = {
getReleaseChannel: {
translations: { callingToolText: 'Reading release settings' },
async onToolCall({ input, addToolOutput }) {
const channel = await readReleaseChannel(input);
await addToolOutput({ output: { channel } });
},
render({ message }) {
const output = message.output as { channel: string };
return `Release channel: ${output.channel}`;
},
},
};

<Sidepanel
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
assistantId="YOUR_AGENT_ID"
indexName="YOUR_INDEX_NAME"
tools={tools}
/>;

Define tools outside the component or memoize it. Tool errors don't render a tool result.

Enable memory

Pass a server-generated Agent Studio user JWT. enabled controls whether memory tool activity appears in the conversation; userToken authenticates the user's memory requests.

Memory.tsx
<Sidepanel
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
assistantId="YOUR_AGENT_ID"
indexName="YOUR_INDEX_NAME"
memory={{
enabled: true,
userToken: userMemoryToken,
}}
/>

Don't generate or sign the token in the browser.

Provide dynamic indices

Use indices to select the indices Agent Studio can search at request time. This list is separate from the required indexName, which remains the Sidepanel's primary index.

DynamicIndices.tsx
<Sidepanel
appId="YOUR_APPLICATION_ID"
apiKey="YOUR_SEARCH_API_KEY"
assistantId="YOUR_AGENT_ID"
indexName="docs"
searchParameters={{
docs: { filters: 'version:v5' },
support_articles: { filters: 'visibility:public' },
}}
indices={['docs', 'support_articles']}
/>

Search parameters are keyed by index name. See the Sidepanel API for the supported fields.