Skip to content
Template Empire
Browse components

Spotlight Quote Carousel

A free testimonial section that spotlights one quote at a time with directional slides.

Customer stories

What teams say after a quarter

Every release used to end in a thread nobody could find six weeks later. The decision, the owner and the evidence now sit in one place, and our postmortems take an hour instead of a day.

Ruth AdeyemiDirector of Product Operations, Northstar

Spotlight Quote Carousel is a free testimonial carousel for Next.js and React that shows one large quote at a time on a bordered surface, opened by an oversized quote mark and closed by a control rail with previous and next buttons and position indicators. Built with Motion and styled with Tailwind, this testimonial carousel for React slides the outgoing quote out through one side while the incoming quote enters from the other on a soft spring, and the direction flips when you step backwards, so navigation always reads as movement through a sequence.

The stage reserves two rows, one for the tallest quote and one for the tallest attribution, so switching between short and long testimonials causes zero layout shift and the author name holds one baseline on every slide, whether the next quote has no role, a one-line role or a role that wraps. The control rail sizes itself to the panel rather than to the viewport, so the arrows and the position markers stay inside a narrow column instead of overflowing it. Auto-advance moves to the next quote every six seconds by default, but only while the carousel is on screen in a visible tab with motion allowed; it pauses on hover and on keyboard focus, and any manual navigation stops it permanently. With prefers-reduced-motion enabled the slides swap as a quick opacity crossfade and the timer never starts. The markup follows the APG carousel pattern with real figure, blockquote and figcaption elements for every quote.

Install

Add the @te registry to your components.json once:

{
  "registries": {
    "@te": "https://templateempire.io/r/{name}.json"
  }
}

Then install the component:

npx shadcn@latest add @te/quote-spotlight-carousel

Usage

import { QuoteSpotlightCarousel } from "@/components/quote-spotlight-carousel";

const quotes = [
  {
    text: "The decision, the owner and the evidence now sit in one place, and our postmortems take an hour instead of a day.",
    name: "Nadia Okonjo",
    role: "Director of Product Operations, Northstar",
  },
  {
    text: "Two quarters in, nobody asks where a decision was made.",
    name: "Tomas Brandt",
    role: "Engineering Manager, Kestrel",
  },
  // ...two to eight quotes total
];

export function Example() {
  return <QuoteSpotlightCarousel quotes={quotes} autoAdvance={6} />;
}

Props

PropTypeDefaultDescription
quotes{ text: string; name: string; role?: string }[]requiredTestimonial quotes shown one at a time, in order. Intended for 2 to 8 quotes.
autoAdvancenumber | false6Seconds each quote stays before auto-advancing, or false to disable the timer entirely. The timer pauses on hover and focus and stops permanently after any manual navigation.
classNamestringundefinedAdditional classes merged onto the section.

Customisation

The quote mark reads --primary-accent, which is mapped to your own primary at install time, and every other surface consumes the semantic colour tokens, so the panel, the rail and the monogram retint with your theme automatically. The slide uses the shared springSoft preset from lib/motion.ts. Adjust the pace with the autoAdvance prop and restyle the panel from the className prop with the same semantic tokens the rest of the library uses:

<QuoteSpotlightCarousel
  quotes={quotes}
  autoAdvance={8}
  className="rounded-xl bg-background"
/>

Frequently asked questions

Is Spotlight Quote Carousel free for commercial use?
Yes. Spotlight Quote Carousel is MIT licensed, so you can use it in personal and commercial projects without attribution.
Is Spotlight Quote Carousel accessible and light on performance?
Yes. The section follows the APG carousel pattern: a labelled region with a carousel role description, the visible slide named N of M, real buttons for previous, next and every position indicator, and aria-current on the active one. Auto-rotation is silent to screen readers, pauses on hover and focus, stops permanently once you navigate manually, and only runs while the carousel is on screen in a visible tab. One timer drives everything, the animation touches transform and opacity only, and the reserved-height stage means zero layout shift. With prefers-reduced-motion enabled the slides crossfade in 150ms and the timer is disabled.
How do I control or disable the auto-advance?
Pass a number of seconds to the autoAdvance prop to set the pace, for example autoAdvance of 8 for a slower rotation, or pass false to disable the timer completely and let visitors page through the quotes themselves. Whatever you choose, any click on the arrows or the position indicators stops the rotation permanently, so the carousel never fights the reader.

Related components

Want the full page this belongs to?Template Empire builds complete Next.js templates with this motion system throughout. Browse the paid templates that pair with these free components.Explore Template Empire templates