Search documentation

Search documentation

Customize your docs experience — choose your preferred framework for code examples:

Customizing the Panel

The panel is the main UI that slides out from the side of the screen.

Basic Options

examples/guides/panel/basic-config.tsx
<PillarProvider
agentSlug="your-agent-slug"
config={{
panel: {
enabled: true,
position: 'right',
mode: 'push',
width: 380,
},
}}
>

Options Reference

enabled
boolean
Whether the panel is enabled.Defaults to true.
position
PanelPosition
Which side of the screen the panel appears on.Defaults to 'right'.
mode
PanelMode
Panel mode: 'overlay' slides over content, 'push' shifts content aside.Defaults to 'push'.
width
number
Panel width in pixels.Defaults to 380.
container
string | HTMLElement | 'manual'
Custom mount point for the panel. - CSS selector string (e.g., '#pillar-panel') - HTMLElement reference - 'manual' for React component-based mounting - undefined (default) mounts to document.body
useShadowDOM
boolean
Whether to use Shadow DOM for style isolation. - false (default): Panel renders in regular DOM, inherits host app CSS. Custom cards can use the host app's design system (Tailwind, etc.) - true: Panel renders in Shadow DOM, fully isolated from host CSS. Use this if you need style isolation on third-party sites.Defaults to false.
hoverBreakpoint
number | false
Viewport width below which the panel switches from 'push' mode to 'hover' mode. In hover mode, the panel floats over content instead of pushing it aside. - number: The breakpoint in pixels (default: 1200) - false: Disable responsive behavior, always use push modeDefaults to 1200.
hoverBackdrop
boolean
Whether to show a backdrop overlay when the panel is in hover mode. Only applies when viewport is below hoverBreakpoint.Defaults to true.
fullWidthBreakpoint
number
Viewport width below which the panel takes full screen width.Defaults to 500.
initialOpen
boolean
Whether to open the panel automatically on initialization. Takes priority over localStorage persisted state.Defaults to false.
resizable
boolean
Whether the panel can be resized by dragging its edge. A drag handle appears on the content-facing edge of the panel when enabled. The resized width is persisted to localStorage.Defaults to true.
pushTarget
string | HTMLElement
Target element for push mode padding. In push mode, padding is applied to this element to make room for the panel. - CSS selector string (e.g., '#main-content', 'body') - HTMLElement reference - undefined (default) applies padding to document.documentElement (html)Defaults to undefined (document.documentElement).

Panel Modes

Push Mode

Content shifts to make room for the panel:

examples/guides/panel/push-mode.tsx
panel: {
mode: 'push',
}

Best for applications where users interact with both the panel and main content.

Overlay Mode

Panel floats over the content:

examples/guides/panel/overlay-mode.tsx
panel: {
mode: 'overlay',
}

Best for minimal layouts or when panel content is the focus.

Responsive Behavior

On smaller screens, the panel automatically switches to overlay mode:

examples/guides/panel/responsive-behavior.tsx
panel: {
mode: 'push',
hoverBreakpoint: 1200, // Switch to overlay below 1200px
hoverBackdrop: true, // Show backdrop when overlaying
}

Disable responsive behavior:

examples/guides/panel/disable-responsive.tsx
panel: {
hoverBreakpoint: false, // Always use push mode
}

Resizing

Users can resize the panel by dragging its inner edge. The resize handle appears on the edge opposite the screen boundary (e.g., the left edge of a right-aligned panel). When the edge trigger is enabled, the resize handle appears between the panel and the trigger. The resized width is persisted to localStorage and restored across page loads.

examples/guides/panel/resizable-config.tsx
<PillarProvider
agentSlug="your-agent-slug"
config={{
panel: {
width: 450, // Default width in pixels
resizable: true, // Allow users to drag-resize (default)
},
}}
>

Disable resizing if you want a fixed-width panel:

examples/guides/panel/disable-resize.tsx
<PillarProvider
agentSlug="your-agent-slug"
config={{
panel: {
width: 400,
resizable: false, // Fixed-width panel, no drag handle
},
}}
>

Custom Placement

Using a Container

Mount the panel to a specific element:

examples/guides/panel/container-selector.tsx
panel: {
container: '#my-panel-container',
}

Or pass an element reference:

examples/guides/panel/container-ref.tsx
<PillarProvider
agentSlug="your-agent-slug"
config={{
panel: { container: '#my-panel-container' }
}}
>
<div id="my-panel-container" />
</PillarProvider>

Manual Placement with PillarPanel

For full control over placement, use container: 'manual' with the PillarPanel component:

examples/guides/panel/manual-placement.tsx
import { PillarProvider, PillarPanel } from '@pillar-ai/react';
function App() {
return (
<PillarProvider
agentSlug="your-agent-slug"
config={{ panel: { container: 'manual' } }}
>
<div className="layout">
<Sidebar />
<main>Your content</main>
<PillarPanel className="custom-panel" />
</div>
</PillarProvider>
);
}

Shadow DOM

By default, the panel inherits your app's CSS. Enable Shadow DOM to isolate the panel's styles from your application:

examples/guides/panel/shadow-dom.tsx
panel: {
useShadowDOM: true,
}

When to use Shadow DOM:

  • Embedding on third-party sites
  • Avoiding CSS conflicts
  • Ensuring consistent appearance

When to avoid Shadow DOM:

  • Inline UI components need your design system
  • You want to style the panel with your CSS

Hiding on Routes

The SDK automatically hides all UI — panel, edge trigger, mobile trigger, and text selection popover — on /login and /signup routes. No configuration needed:

examples/guides/panel/exclude-routes-default.tsx
// No config needed — /login and /signup are excluded by default.
// The SDK automatically hides on these routes.
<PillarProvider agentSlug="your-agent-slug">
{children}
</PillarProvider>

Custom Excluded Routes

Add your own routes to the list:

examples/guides/panel/exclude-routes-custom.tsx
<PillarProvider
agentSlug="your-agent-slug"
config={{
excludeRoutes: ['/login', '/signup', '/onboarding', '/maintenance'],
}}
>
{children}
</PillarProvider>

Route matching uses prefix logic: /login matches /login, /login/sso, and /login/forgot-password, but not /login-history.

Show on Every Route

Pass an empty array to disable route exclusion entirely:

examples/guides/panel/exclude-routes-disable.tsx
<PillarProvider
agentSlug="your-agent-slug"
config={{
excludeRoutes: [],
}}
>
{children}
</PillarProvider>

Next Steps