Open source React achievement badge component with locked/unlocked states, progress rings and rarity support. Use for achievement UI design and collections. Built on shadcn/ui + Tailwind.
The Achievement Badge is the atomic unit of achievement gamification UI—a compact tile users recognize from games and productivity apps, with progress and rarity built in. Compose with Achievement Card and Achievement Grid when you need achievement gamification at scale.
Consistency I
Installation
npx shadcn@latest add https://ui.trophy.so/achievement-badgeUsage
import { AchievementBadge } from "@/components/ui/achievement-badge"<AchievementBadge
achievement={{
id: "1",
name: "Consistency I",
trigger: "streak",
achievedAt: "2024-01-01T00:00:00Z",
progress: 28,
}}
/>Examples
Basic Usage
Consistency I
<AchievementBadge
achievement={{
id: "1",
name: "Consistency I",
trigger: "streak",
achievedAt: "2024-01-01T00:00:00Z",
progress: 28,
}}
/>Badge Sizes
Early Bird
Early Bird
Early Bird
Early Bird
<AchievementBadge
achievement={{
id: "1",
name: "Consistency I",
trigger: "streak",
achievedAt: "2024-01-01T00:00:00Z",
progress: 28,
}}
badgeSize="sm"
/>
<AchievementBadge
achievement={{
id: "1",
name: "Consistency I",
trigger: "streak",
achievedAt: "2024-01-01T00:00:00Z",
progress: 28,
}}
badgeSize="default"
/>
<AchievementBadge
achievement={{
id: "1",
name: "Consistency I",
trigger: "streak",
achievedAt: "2024-01-01T00:00:00Z",
progress: 28,
}}
badgeSize="lg"
/>
<AchievementBadge
achievement={{
id: "1",
name: "Consistency I",
trigger: "streak",
achievedAt: "2024-01-01T00:00:00Z",
progress: 28,
}}
badgeSize="xl"
/>Locked State
When achievement.achievedAt is null, the badge is shown in a locked state.
Consistency I
Perfectionist
<AchievementBadge
achievement={{
id: "badge-1",
name: "Consistency I",
trigger: "streak",
achievedAt: "2024-01-01T00:00:00Z",
}}
/>
<AchievementBadge
achievement={{
id: "badge-locked-1",
name: "Perfectionist",
trigger: "metric",
achievedAt: null,
}}
/>Series Progress
Consistency I
Consistency II
Consistency III
Consistency IV
<AchievementBadge
achievement={{
id: "series-1",
name: "Consistency I",
trigger: "streak",
achievedAt: "2024-01-01T00:00:00Z",
progress: 28,
}}
/>Rarity
3% of usersDaily Legend
12% of usersPower User
41% of usersFinisher
78% of usersFirst Win
<AchievementBadge
achievement={{
id: "rare-1",
name: "Daily Legend",
trigger: "streak",
achievedAt: "2024-01-01T00:00:00Z",
rarity: 3,
}}
/>Clickable Achievement
Consistency I
<AchievementBadge
achievement={{
id: "1",
name: "Consistency I",
trigger: "streak",
achievedAt: "2024-01-01T00:00:00Z",
progress: 28,
}}
onAchievementClick={(achievement) => {
openDetailModal(achievement)
}}
/>With Trophy
Use the Trophy SDK to fetch a user's achievements server-side:
import { TrophyApiClient } from '@trophyso/node';
const trophy = new TrophyApiClient({
apiKey: 'YOUR_API_KEY'
});
const response = await trophy.users.achievements("user-id");
Then pass the response into AchievementBadge props in your UI layer:
const achievement = response[0]
<AchievementBadge achievement={achievement} />API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
achievement | UserAchievement | Required | Achievement data for this badge |
badgeSize | "sm" | "default" | "lg" | "xl" | "default" | Badge size |
onAchievementClick | (achievement) => void | - | Click handler |
Types
interface Achievement {
id: string
name: string
trigger: "metric" | "api" | "streak"
badgeUrl?: string | null
progress?: number // optional series progress from 0 to 100, unlocked only
rarity?: number // optional rarity from 1 to 100 shown as "X% of users"
}
interface UserAchievement extends Achievement {
achievedAt: string | null // null = locked
}Power Gamification with Trophy
Trophy powers the infrastructure you need to ship reliable gamification features at scale.
Get Started