showcase/shell-docs/src/content/reference/hooks/useRenderTool.mdx
useRenderTool registers a chat renderer for tool calls.
You can target a specific tool name (with a typed Zod parameters schema) or use a wildcard ("*") fallback renderer.
This is part of the v2 tool rendering hook set with useComponent, useDefaultRenderTool, and useRenderToolCall.
This hook only handles rendering. It does not register a frontend handler.
import { useRenderTool } from "@copilotkit/react-core/v2";
useRenderTool(
{
name: "*",
render: (props) => React.ReactElement,
agentId?: string,
},
deps?: ReadonlyArray<unknown>,
);
import { z } from "zod";
import { useRenderTool } from "@copilotkit/react-core/v2";
useRenderTool(
{
name: string,
parameters: z.ZodTypeAny,
render: (props) => React.ReactElement,
agentId?: string,
},
deps?: ReadonlyArray<unknown>,
);
render receives one of these states:
{ status: "inProgress", parameters: Partial<T>, result: undefined }{ status: "executing", parameters: T, result: undefined }{ status: "complete", parameters: T, result: string }name is always present in all states.
defineToolCallRenderer.agentId:name key (latest registration wins).config.name plus values in deps (include changing captures in deps).function App() {
useRenderTool(
{
name: "searchDocs",
parameters: z.object({ query: z.string() }),
render: ({ name, parameters, status, result }) => {
if (status === "inProgress") return <div>Preparing {name}…</div>;
if (status === "executing")
return <div>Searching for: {parameters.query}</div>;
return <div>Done: {result}</div>;
},
},
[],
);
return null;
}
function App() {
useRenderTool(
{
name: "*",
render: ({ name, status }) => (
<div>
{status === "complete" ? "✓" : "⏳"} {name}
</div>
),
},
[],
);
return null;
}