Skip to content

TwitterCard (Component)

Description

The TwitterCard component displays real-time Twitter/X posts as testimonials or social proof. It fetches live tweet data using the X API and presents it in a beautiful, modern card format perfect for showcasing customer feedback and testimonials.

Preview

Twitter Card Component Preview
*Modern Twitter card displaying real tweet data with author info, content, and engagement metrics*

Features

  • Real-time data fetched from X API
  • Author information with profile and username
  • Formatted dates in French locale
  • Engagement metrics (likes, retweets)
  • Direct links to original tweets
  • Responsive design with hover effects
  • Loading states with skeleton animation
  • Modern styling with shadcn/ui design system

Usage

Basic Usage

vue
<template>
  <TwitterCard tweet-url="https://x.com/mhdevfr/status/1963265765341040667" />
</template>

In Testimonials Section

vue
<template>
  <section class="py-16 bg-gray-50">
    <div class="max-w-6xl mx-auto px-4">
      <h2 class="text-3xl font-bold text-center mb-12">
        What Our Users Say
      </h2>
      
      <div class="grid md:grid-cols-2 lg:grid-cols-3 gap-6">
        <TwitterCard 
          tweet-url="https://x.com/user1/status/1234567890"
        />
        <TwitterCard 
          tweet-url="https://x.com/user2/status/1234567891"
        />
        <TwitterCard 
          tweet-url="https://x.com/user3/status/1234567892"
        />
      </div>
    </div>
  </section>
</template>

With Custom Styling

vue
<template>
  <div class="testimonials-grid">
    <TwitterCard 
      tweet-url="https://x.com/mhdevfr/status/1963265765341040667"
      class="testimonial-card"
    />
  </div>
</template>

<style>
.testimonial-card {
  transform: scale(1.05);
  box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
}

.testimonial-card:hover {
  transform: scale(1.08);
}
</style>

Props

PropTypeRequiredDescription
tweetUrlstringFull Twitter/X URL of the tweet

API Configuration

X API Setup

To use the TwitterCard component, you need to configure the X API:

1. Create X Developer Account

  1. Go to X Developer Portal
  2. Create a new project
  3. Generate API keys and tokens

2. Environment Variables

Add these to your .env file:

bash
# X API Configuration
X_API_KEY=your_x_api_key
X_API_SECRET=your_x_api_secret
X_BEARER_TOKEN=your_x_bearer_token

3. API Routes

The component uses these API endpoints:

typescript
// server/api/twitter/tweet/[id].get.ts
export default defineEventHandler(async (event) => {
  const tweetId = getRouterParam(event, 'id')
  const config = useRuntimeConfig()
  
  const response = await $fetch(`https://api.twitter.com/2/tweets/${tweetId}`, {
    params: {
      'tweet.fields': 'created_at,public_metrics,text',
      'user.fields': 'name,username,profile_image_url',
      'expansions': 'author_id'
    },
    headers: {
      'Authorization': `Bearer ${config.xBearerToken}`
    }
  })
  
  return response
})

Data Structure

The component fetches and displays:

typescript
interface TwitterData {
  id: string
  text: string
  author: {
    name: string
    username: string
    profile_image_url?: string
  }
  created_at: string
  public_metrics?: {
    like_count: number
    retweet_count: number
    reply_count: number
    quote_count: number
  }
}

Examples

Customer Testimonials

vue
<template>
  <section class="testimonials">
    <div class="container">
      <h2>Customer Love</h2>
      <div class="testimonials-grid">
        <TwitterCard 
          tweet-url="https://x.com/customer1/status/1234567890"
        />
        <TwitterCard 
          tweet-url="https://x.com/customer2/status/1234567891"
        />
        <TwitterCard 
          tweet-url="https://x.com/customer3/status/1234567892"
        />
      </div>
    </div>
  </section>
</template>

<style>
.testimonials-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.5rem;
}
</style>

Product Reviews

vue
<template>
  <div class="reviews-section">
    <h3>Product Reviews</h3>
    <div class="reviews-list">
      <TwitterCard 
        v-for="review in reviews"
        :key="review.id"
        :tweet-url="review.tweetUrl"
      />
    </div>
  </div>
</template>

<script setup>
const reviews = [
  {
    id: 1,
    tweetUrl: 'https://x.com/reviewer1/status/1234567890'
  },
  {
    id: 2,
    tweetUrl: 'https://x.com/reviewer2/status/1234567891'
  }
]
</script>

Social Proof Section

vue
<template>
  <section class="social-proof">
    <div class="max-w-4xl mx-auto text-center">
      <h2 class="text-4xl font-bold mb-8">
        Trusted by Developers Worldwide
      </h2>
      <p class="text-xl text-gray-600 mb-12">
        See what developers are saying about ClawPlate
      </p>
      
      <div class="grid md:grid-cols-2 gap-8">
        <TwitterCard 
          tweet-url="https://x.com/dev1/status/1963265765341040667"
        />
        <TwitterCard 
          tweet-url="https://x.com/dev2/status/1963265765341040668"
        />
      </div>
      
      <div class="mt-8">
        <a 
          href="https://x.com/search?q=clawplate"
          target="_blank"
          class="inline-flex items-center px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700"
        >
          <Icon name="simple-icons:x" class="w-5 h-5 mr-2" />
          See More on X
        </a>
      </div>
    </div>
  </section>
</template>

Styling

The component uses Tailwind CSS with shadcn/ui design tokens:

Custom Themes

vue
<template>
  <TwitterCard 
    tweet-url="https://x.com/user/status/1234567890"
    class="custom-twitter-card"
  />
</template>

<style>
.custom-twitter-card {
  @apply bg-gradient-to-br from-blue-50 to-indigo-50;
  @apply border-blue-200;
}

.custom-twitter-card:hover {
  @apply shadow-2xl;
  @apply transform scale-105;
}
</style>

Dark Mode Support

The component automatically adapts to dark mode:

css
.dark .twitter-card {
  background-color: #1f2937;
  border-color: #374151;
}

Error Handling

The component includes fallback mechanisms:

  1. Primary API: X API v2 for full tweet data
  2. Fallback API: oEmbed API for basic tweet info
  3. Loading States: Skeleton animation during fetch
  4. Error States: Graceful degradation if APIs fail

Performance

Caching Strategy

typescript
// server/api/twitter/tweet/[id].get.ts
const cache = new Map()

export default defineEventHandler(async (event) => {
  const tweetId = getRouterParam(event, 'id')
  
  // Check cache first
  if (cache.has(tweetId)) {
    return cache.get(tweetId)
  }
  
  // Fetch from API
  const data = await fetchTweetData(tweetId)
  
  // Cache for 5 minutes
  cache.set(tweetId, data)
  setTimeout(() => cache.delete(tweetId), 5 * 60 * 1000)
  
  return data
})

Rate Limiting

typescript
// Implement rate limiting
const rateLimiter = new Map()

export default defineEventHandler(async (event) => {
  const clientIP = getClientIP(event)
  const now = Date.now()
  
  if (rateLimiter.has(clientIP)) {
    const lastRequest = rateLimiter.get(clientIP)
    if (now - lastRequest < 1000) { // 1 second cooldown
      throw createError({
        statusCode: 429,
        statusMessage: 'Too Many Requests'
      })
    }
  }
  
  rateLimiter.set(clientIP, now)
  // ... rest of handler
})

Best Practices

For Testimonials

  1. Curate Quality Tweets: Choose tweets that highlight specific benefits
  2. Mix Content Types: Include different types of feedback (reviews, use cases, etc.)
  3. Regular Updates: Refresh testimonials regularly to show recent feedback
  4. Permission: Always ask permission before featuring customer tweets

For Performance

  1. Cache Responses: Implement caching to reduce API calls
  2. Lazy Loading: Load Twitter cards only when they're visible
  3. Error Boundaries: Handle API failures gracefully
  4. Rate Limiting: Implement proper rate limiting

For Accessibility

  1. Alt Text: Ensure images have proper alt text
  2. Keyboard Navigation: Make sure all links are keyboard accessible
  3. Screen Readers: Test with screen readers
  4. Color Contrast: Ensure sufficient color contrast

Troubleshooting

Common Issues

API Rate Limits

  • Implement proper caching
  • Use fallback oEmbed API
  • Consider pre-fetching popular tweets

Tweet Not Loading

  • Check if tweet is public
  • Verify API credentials
  • Check network connectivity

Styling Issues

  • Ensure Tailwind CSS is loaded
  • Check for CSS conflicts
  • Verify dark mode classes

This component is part of the ClawPlate suite and is perfect for showcasing real customer testimonials and social proof.

Built with love by mhdevfr