# Dynamic Control URL: /concepts/additional-context/dynamic-control Context helpers can be dynamically managed using the `useTamboContextHelpers` hook. ## Available Functions ```tsx import { useTamboContextHelpers } from "@tambo-ai/react"; const { getContextHelpers, // Get the current map of helpers addContextHelper, // Add or replace a helper removeContextHelper, // Remove a helper } = useTamboContextHelpers(); ``` **Note:** * Helpers are just functions; to “disable” a helper, replace it with a function that returns null. * You can also configure helpers declaratively using `TamboContextHelpersProvider`; both approaches write to the same global registry. ## Add/Replace Helpers at Runtime Useful when context depends on user actions or app state: ```tsx function ProjectContextController({ projectId }: { projectId: string }) { const { addContextHelper, removeContextHelper } = useTamboContextHelpers(); useEffect(() => { if (!projectId) return; addContextHelper("currentProject", async () => ({ projectId, projectName: await getProjectName(projectId), projectData: await getProjectData(projectId), })); return () => { removeContextHelper("currentProject"); }; }, [projectId]); return null; } ``` ## Removing Helpers ```tsx const { removeContextHelper } = useTamboContextHelpers(); // User logs out removeContextHelper("session"); ``` ## Building a Settings UI `getContextHelpers` returns the current map of helper functions keyed by name. You can build toggles by swapping in a real function or a no-op function that returns null: ```tsx function ContextSettings() { const { getContextHelpers, addContextHelper } = useTamboContextHelpers(); const helpers = getContextHelpers(); return (

Privacy Settings

{Object.keys(helpers).map((key) => (
{key}
))}
); } ``` ## Register helpers from multiple pages using the Provider You can also register helpers declaratively at the page or layout level with `TamboContextHelpersProvider`. Helpers are registered when the provider mounts and are active only while that provider remains mounted (for example, while you’re on that page/layout). If the same key is registered multiple times at different times, the most recently mounted provider takes effect for as long as it’s mounted. **App layout (optional global helpers):** ```tsx title="app/layout.tsx" import { TamboProvider, TamboContextHelpersProvider } from "@tambo-ai/react"; import { currentTimeContextHelper } from "@tambo-ai/react"; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( ); } ``` **Page A (adds a page-specific helper):** ```tsx title="app/dashboard/page.tsx" "use client"; import { TamboContextHelpersProvider } from "@tambo-ai/react"; import { currentPageContextHelper } from "@tambo-ai/react"; import { MessageThreadFull } from "@/components/tambo/message-thread-full"; export default function DashboardPage() { return ( ); } ``` **Page B (adds a different helper or overrides a key):** ```tsx title="app/settings/page.tsx" "use client"; import { TamboContextHelpersProvider } from "@tambo-ai/react"; const getUserSettingsContext = async () => ({ theme: "dark", notifications: true, }); export default function SettingsPage() { return ( ({ url: "/settings", title: "Settings" }), }} > {/* Components that send messages */} ); } ``` * If you only want a helper active while a page is mounted, register it in that page’s provider (like above), or use the hook with add/remove in a `useEffect` with cleanup. * Consider namespacing keys if multiple parts of the app might register the same context (e.g., `dashboard:userPage`). ## What Happens Behind the Scenes When you send a message, Tambo automatically: 1. Calls all configured helper functions. 2. Filters out null/undefined results. 3. Merges the results with any manual `additionalContext`. 4. Sends everything with the message.