shadcn-ui/ui · error · Error
useBlockViewer must be used within a BlockViewerProvider.
Error message
useBlockViewer must be used within a BlockViewerProvider.
What it means
`useBlockViewer` reads `BlockViewerContext` (`createContext<BlockViewerContext | null>(null)`). `BlockViewerProvider` supplies `item`, `tree`, `highlightedFiles`, plus state (`iframeKey`, etc.). Any consumer for which `useContext` returns null throws — the block viewer sub-components (file tree, code view, iframe) all assume these props exist.
Source
Thrown at apps/v4/components/block-viewer.tsx:87
activeFile: string | null
setActiveFile: (file: string) => void
resizablePanelRef: React.RefObject<PanelImperativeHandle | null> | null
tree: ReturnType<typeof createFileTreeForRegistryItemFiles> | null
highlightedFiles:
| (z.infer<typeof registryItemFileSchema> & {
highlightedContent: string
})[]
| null
iframeKey?: number
setIframeKey?: React.Dispatch<React.SetStateAction<number>>
}
const BlockViewerContext = React.createContext<BlockViewerContext | null>(null)
function useBlockViewer() {
const context = React.useContext(BlockViewerContext)
if (!context) {
throw new Error("useBlockViewer must be used within a BlockViewerProvider.")
}
return context
}
function BlockViewerProvider({
item,
tree,
highlightedFiles,
children,
}: Pick<BlockViewerContext, "item" | "tree" | "highlightedFiles"> & {
children: React.ReactNode
}) {
const [view, setView] = React.useState<BlockViewerContext["view"]>("preview")
const [activeFile, setActiveFile] = React.useState<
BlockViewerContext["activeFile"]
>(highlightedFiles?.[0].target ?? null)
const resizablePanelRef = React.useRef<PanelImperativeHandle>(null)
const [iframeKey, setIframeKey] = React.useState(0)View on GitHub (pinned to efac598707)
Solutions
- Always mount `<BlockViewerProvider item tree highlightedFiles>` above any sub-component that calls `useBlockViewer()`.
- Pass the required props (`item`, `tree`, `highlightedFiles`) to the provider — it does not default them.
- In tests/stories, render the whole `<BlockViewerProvider>` wrapper with stub props.
Example fix
// before
<BlockViewerFiles />
// after
<BlockViewerProvider item={item} tree={tree} highlightedFiles={files}>
<BlockViewerFiles />
</BlockViewerProvider> Defensive patterns
Strategy: type-guard
Validate before calling
render(<BlockViewerProvider item={stubItem} tree={stubTree} highlightedFiles={stubFiles}>{<BlockViewerFiles/>}</BlockViewerProvider>) Type guard
import React from "react"
import { BlockViewerContext } from "@/components/block-viewer"
const hasBlockViewer = () => React.useContext(BlockViewerContext) != null Try / catch
try { useBlockViewer() } catch (e) { if (e.message.includes("BlockViewerProvider")) {/*mount with required props*/} throw e } Prevention
- Always pass item/tree/highlightedFiles to BlockViewerProvider — they are required.
- Render block-viewer parts only inside the provider subtree.
- Provide stub fixtures for tests/stories.
When it happens
Trigger: Rendering a block-viewer child (e.g. `<BlockViewerFiles />`, `<BlockViewerIframe />`) outside `<BlockViewerProvider item={...} tree={...} highlightedFiles={...}>`. Common when composing the viewer from parts without the provider, or rendering a single part in isolation.
Common situations: Splitting the block viewer into composable parts; rendering a part inside a portal detached from the provider tree; storybook stories of individual parts.
Related errors
- usePreviewOverride must be used within a PreviewOverrideProv
- useHistory must be used within HistoryProvider
- useLocks must be used within LocksProvider
- usePreviewOverride must be used within a TypesetPreviewOverr
- useHistory must be used within TypesetHistoryProvider
AI-assisted analysis of shadcn-ui/ui@efac598707 (2026-08-12).
Data as JSON: /api/errors/271f8b7bf4acf538.
Report an issue: GitHub.