{"record":{"id":"9995f688af9cf7db","repo":"shadcn-ui/ui","slug":"usecarousel-must-be-used-within-a-carousel-9995f6","errorCode":null,"errorMessage":"useCarousel must be used within a <Carousel />","messagePattern":"useCarousel must be used within a <Carousel />","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/v4/registry/bases/base/ui/carousel.tsx","lineNumber":39,"sourceCode":"  setApi?: (api: CarouselApi) => void\n}\n\ntype CarouselContextProps = {\n  carouselRef: ReturnType<typeof useEmblaCarousel>[0]\n  api: ReturnType<typeof useEmblaCarousel>[1]\n  scrollPrev: () => void\n  scrollNext: () => void\n  canScrollPrev: boolean\n  canScrollNext: boolean\n} & CarouselProps\n\nconst CarouselContext = React.createContext<CarouselContextProps | null>(null)\n\nfunction useCarousel() {\n  const context = React.useContext(CarouselContext)\n\n  if (!context) {\n    throw new Error(\"useCarousel must be used within a <Carousel />\")\n  }\n\n  return context\n}\n\nfunction Carousel({\n  orientation = \"horizontal\",\n  opts,\n  setApi,\n  plugins,\n  className,\n  children,\n  ...props\n}: React.ComponentProps<\"div\"> & CarouselProps) {\n  const [carouselRef, api] = useEmblaCarousel(\n    {\n      ...opts,\n      axis: orientation === \"horizontal\" ? \"x\" : \"y\",","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/shadcn-ui/ui/blob/efac5987074af84ece57c367c6dd83387b967022/apps/v4/registry/bases/base/ui/carousel.tsx#L21-L57","documentation":"Identical contract to [151] but in the `base` style registry. `useCarousel` reads `CarouselContext`; carousel sub-parts rendered outside `<Carousel>` throw so the embla api is never null.","triggerScenarios":"Mounting `<CarouselPrevious />` / `<CarouselNext />` / `<CarouselItem />` outside `<Carousel>` when importing from the `base` style. Same shape as the aria variant.","commonSituations":"Using the `base` (non-aria) style and copying markup that places buttons outside Carousel; composing a custom layout; tests of individual parts.","solutions":["Nest all Carousel sub-components under `<Carousel>` from the `base` style import path.","Keep buttons inside the Carousel subtree even when CSS-positioned elsewhere.","Decorate tests/stories with `<Carousel>`."],"exampleFix":"// before\n<Carousel />\n<CarouselNext />\n\n// after\n<Carousel>\n  <CarouselItems>\n    <CarouselItem>...</CarouselItem>\n  </CarouselItems>\n  <CarouselPrevious />\n  <CarouselNext />\n</Carousel>","handlingStrategy":"type-guard","validationCode":"render(<Carousel><CarouselItems><CarouselItem>x</CarouselItem></CarouselItems><CarouselPrevious/><CarouselNext/></Carousel>) // base style imports","typeGuard":"import React from \"react\"\nimport { CarouselContext } from \"@/registry/bases/base/ui/carousel\"\nconst insideCarousel = () => React.useContext(CarouselContext) != null","tryCatchPattern":"try { useCarousel() } catch (e) { if (e.message.includes(\"<Carousel />\")) {/*nest inside Carousel*/} throw e }","preventionTips":["Nest base-style Carousel parts under the base-style <Carousel>.","Keep buttons inside the tree even when CSS-positioned outside.","Add the base-style <Carousel> to story/test decorators."],"tags":["react","context","hooks","shadcn","carousel","base-style"],"backgroundTag":null,"analyzedSha":"efac5987074af84ece57c367c6dd83387b967022","analyzedAt":"2026-08-12T05:00:50.218Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}