DEV Community

Cover image for How to create an interactive pricing table with Astro, Tailwind CSS, and Alpine.js
Michael Andreuzza
Michael Andreuzza

Posted on

How to create an interactive pricing table with Astro, Tailwind CSS, and Alpine.js

This tutorial delves into creating a responsive and interactive pricing table component, leveraging the powerful combination of Astro for static generation, Tailwind CSS for styling, and Alpine.js for interactivity. Our focus will be on the dynamic aspects of the component, particularly how Alpine.js works and how Astro passes data through an array to render our pricing plans.
See it live and get the code

Let's populate the array for the pricing plans

Starting with the pricingPlans array, the backbone of our component. This array contains objects, each representing a different pricing plan and styles for our pricing cards, because of course, we need to think about UX.

const pricingPlans = [
  {
    name: "Starter Pack",
    monthlyPrice: "15",
    annualPrice: "8",
    description: "This plan is ideal for individual users...",
    cardBgClass: "bg-black/20",
    buttonClass: "text-white bg-black/50 hover:bg-black/20",
    features: ["5 mb/PDF", "75 pages/PDF"],
    unavailableFeatures: ["Gpt-3.5-turbo model"],
  },
  // More plans...
];
Enter fullscreen mode Exit fullscreen mode

Each plan includes details such as pricing, descriptions, styling classes, and arrays of available and unavailable features.

Rendering the Component with Astro

Using Astro's component model, we dynamically render each pricing plan. Astro's template syntax allows us to iterate over the pricingPlans array, generating the markup for each plan:

---
// Import statements and the pricingPlans array defined here
---
<BaseLayout>
  <div x-data="{ annual: false }">
    <!-- Pricing Plans Rendering -->
    {pricingPlans.map((plan) => (
      <div class={`rounded-xl overflow-hidden shadow-lg ${plan.cardBgClass}`}>
        <!-- Content goes here -->
      </div>
    ))}
  </div>
</BaseLayout>
Enter fullscreen mode Exit fullscreen mode

Styling with Tailwind CSS

Within each plan's markup, Tailwind CSS classes are applied for styling. This approach ensures our pricing table is not only functional but also visually appealing and responsive:

<div class="text-xl font-semibold text-gray-800">{plan.name}</div>
<div class="mt-4">
  <span class="text-4xl font-bold">${plan.monthlyPrice}</span>
  <span class="text-base">/ month</span>
</div>
<!-- More styling with Tailwind CSS -->
Enter fullscreen mode Exit fullscreen mode

For each pricing plan, we conditionally display the price based on this state:

<p>
  <span x-show="!annual">${plan.monthlyPrice}</span>
  <span x-show="annual">${plan.annualPrice}</span>
  /month
</p>
Enter fullscreen mode Exit fullscreen mode

Dynamic Feature Listing

A key part of our pricing table is listing what's included and what's not. Using Alpine.js's x-show, we dynamically render features based on their availability:

<ul>
  {plan.features.map((feature) => (
    <li x-show="available">
       <!-- Icons goes here -->
      {feature}
      </li>
  ))}
  {plan.unavailableFeatures.map((feature) => (
    <li x-show="!available" class="text-gray-500">
    <!-- Icons goes here -->
    {feature}</li>
  ))}
</ul>
Enter fullscreen mode Exit fullscreen mode

By combining Astro's static generation with Tailwind CSS for styling and Alpine.js for interactivity, we've created a dynamic and responsive pricing table component. This tutorial showcases the power of integrating these modern web technologies to build interactive components efficiently.

Experiment with the code snippets provided, tweaking styles, and adding more features as you see fit. The flexibility of Astro, combined with the utility-first approach of Tailwind CSS and the reactivity of Alpine.js, offers a solid foundation for building sophisticated web interfaces.

Top comments (0)