How to create an interactive testimonial with Astrojs, Tailwind CSS and Alpine.js

The image is a graphic with a purple gradient background. At the center, there is a stylized quote in quotation marks with white and light purple text
Wed Mar 06 2024 Author ✺ Michael Andreuzza

Let’s build a fun testimonial with Astro, Tailwind CSS and Alpinejs!

The main thing

Let’s use Astro to make a template so we don’t have to write the same code over and over. We’ll put our data in an array and send it to the Alpine.js component.

The array

This array represents a single testimonial object within a larger collection of testimonials. Each object in the collection includes several key pieces of information about the testimonial:

  • id: Unique identifier for each testimonial.
  • content: The testimonial text.
  • imageUrl: Link or path to an associated image.
  • name: The name of the testimonial provider.
  • title: Their professional title or role.

Here’s the code snippet for the testimonial object:

{
    id: 1,
    content:
      "Johnny is like a unicorn in a field of horses, magically bridging the gap between design and coding...",
    imageUrl:
      "https://images.unsplash.com/photo-1543610892-0b1f7e6d8ac1?w=800&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8MjN8fGF2YXRhcnxlbnwwfHwwfHx8MA%3D%3D",
    name: "Jhonny Mnemonic",
    title: "Chief Wizard of Nowhere Land",
},

Implementing the Astro Template

Alpine.js facilitates the interactive elements within the testimonials section through:

  1. State Management: x-data initializes a component state, testimonialActive, which tracks the currently active testimonial. This state is crucial for determining which testimonial content to display.

In this cse we are using the 1 testimonial

<div x-data="{ testimonialActive: 1 }">

Adjust the number in testimonialActive to set a different default testimonial.

2.3. Conditional Rendering: x-show directive dynamically shows or hides a testimonial based on whether its index matches the testimonialActive state.

<div x-show={`testimonialActive === ${index + 1}`}>

Complete component for rendering testimonials dynamically:

 <!-- Dynamically render testimonials -->
{
  testimonials.map((testimonial, index) => (
    <div
      class="pb-6 text-gray-200 font-medium mx-auto lg:h-64 italic serif text-balance items-center text-center text-4xl "
      x-show={`testimonialActive === ${index + 1}`}
      style="display: none;">
      <p>
        <span class="text-[#a180ea]">"</span>
        {testimonial.content}
        <span class="text-[#a180ea]">"</span>
      </p>
    </div>
  ))
}
<!-- Dynamically render name and role  -->
{
  testimonials.map((testimonial, index) => (
    <div
      class="text-center py-6"
      x-show={`testimonialActive === ${index + 1}`}
      style="display: none;">
      <h2 class="text-white  font-medium text-base">{testimonial.name}</h2>
      <a
        href="#"
        class="text-xs text-gray-400">
        {testimonial.title}
      </a>
    </div>
  ))
}
  1. Event Handling: @click.prevent to change the active testimonial based on the user’s selection..
<button @click.prevent={`testimonialActive = ${index + 1}`}>

For navigating between testimonials:

<!--
Buttons to change the active testimonial
Dynamically render avatars
-->
{
  testimonials.map((testimonial, index) => (
    <button
      @click.prevent={`testimonialActive = ${index + 1}`}
      class="inline-block mx-2 font-bold text-center rounded-xl  focus:outline-none focus:ring-2 ring-offset-2  ring-white ring-offset-[#141521] size-12">
      <img
        class="inline-block size-12 rounded-xl object-cover"
        src={testimonial.imageUrl}
        alt="#_"
      />
    </button>
  ))
}

That was it, short, brief and straight to the point, don’t forget to grab the code and do something cool with it!

Did you like this tutorial? Please share it with your friends!

Reviews and opinions

  • "I bought a beautiful theme from Lexington a couple weeks ago. I didn't know Astro at the time, but Michael helped me get set up and really went above and beyond with his support. Now I'm happily redoing my site to look gorgeous with his template."

    Stuart

    Stuart

    Creator of saasydb.com

  • "Michael is one of the best designers on Twitter, would highly recommend his Lexington Themes if you want something in tailwind that doesn’t look the same as everyone else!"

    Alex Hughes

    Alex Hughes

    letsloopin.com

Get lifetime access to every theme available today for $199 and own them forever. Plus, new themes, lifetime updates, use on unlimited projects and enjoy lifetime support.

No subscription required!

Lexington

Beautifully designed HTML, Astro.js and Tailwind themes! Save months of time and build your startup landing page in minutes.