Data Version Display System
Ever Works includes a data versioning system that shows users the current version of data they're viewing, providing transparency about content freshness.
Overviewβ
The system provides:
- π Real-time version display - Shows current data repository version
- π Auto-refresh - Periodically updates version information
- π¨ Multiple variants - Badge, inline, and detailed views
- π‘ Tooltip details - Hover for comprehensive information
- β‘ ISR support - Works with Incremental Static Regeneration
- π‘οΈ Error handling - Graceful fallback when unavailable
Architectureβ
Componentsβ
VersionDisplayβ
Main component for displaying version information.
import { VersionDisplay } from "@/components/version";
// Basic inline display
<VersionDisplay variant="inline" />
// Badge variant
<VersionDisplay variant="badge" />
// Detailed view with additional information
<VersionDisplay variant="detailed" showDetails={true} />
Props:
variant:"inline" | "badge" | "detailed"- Display styleshowDetails:boolean- Show extended information (detailed variant only)className:string- Additional CSS classesrefreshInterval:number- Auto-refresh interval in ms (default: 5 minutes)
VersionTooltipβ
Wrapper component that adds a tooltip with detailed version information.
import { VersionTooltip } from "@/components/version";
<VersionTooltip>
<VersionDisplay variant="badge" />
</VersionTooltip>
Features:
- Shows commit hash and date
- Displays commit message
- Shows author information
- Links to repository
useVersionInfo Hookβ
Custom hook for managing version information with caching and auto-refresh.
import { useVersionInfo } from "@/hooks/use-version-info";
const { versionInfo, loading, error, refetch } = useVersionInfo({
refreshInterval: 5 * 60 * 1000, // 5 minutes
retryOnError: true,
retryDelay: 10000
});
Returns:
versionInfo: Version data objectloading: Loading stateerror: Error staterefetch: Manual refresh function
API Endpointβ
GET /api/versionβ
Returns current data repository version information.
Response:
{
"commit": "abc1234",
"date": "2024-01-01T12:00:00.000Z",
"message": "Update data items",
"author": "Developer Name",
"repository": "https://github.com/owner/repo",
"lastSync": "2024-01-01T12:05:00.000Z"
}
Features:
- Automatic repository sync before fetching
- Proper cache headers for optimal performance
- ETag support for efficient caching
- Error handling with appropriate HTTP status codes
Cache Headers:
Cache-Control: public, s-maxage=60, stale-while-revalidate=300
ETag: "abc1234"
Configurationβ
Environment Variablesβ
# Data repository URL
DATA_REPOSITORY=https://github.com/your-org/your-data-repo
# GitHub token for private repositories (optional)
GH_TOKEN=ghp_your_github_token_here
# Repository sync interval (optional, default: 5 minutes)
REPO_SYNC_INTERVAL=300000
Caching Strategyβ
Client-side Cacheβ
- Duration: 1 minute
- Strategy: stale-while-revalidate
- Refresh: Automatic background updates
Server-side Cacheβ
- Duration: 60 seconds
- Strategy: s-maxage with revalidation
- ETag: Commit hash-based
Usage Examplesβ
Footer Version Badgeβ
// components/footer/Footer.tsx
import { VersionDisplay } from "@/components/version";
export function Footer() {
return (
<footer>
<div className="container">
<p>Β© 2024 Ever Works</p>
<VersionDisplay variant="badge" />
</div>
</footer>
);
}
Admin Dashboardβ
// app/admin/dashboard/page.tsx
import { VersionDisplay } from "@/components/version";
export default function AdminDashboard() {
return (
<div>
<h1>Admin Dashboard</h1>
<VersionDisplay
variant="detailed"
showDetails={true}
refreshInterval={60000} // 1 minute
/>
</div>
);
}
Custom Implementationβ
import { useVersionInfo } from "@/hooks/use-version-info";
export function CustomVersionDisplay() {
const { versionInfo, loading, error, refetch } = useVersionInfo();
if (loading) return <div>Loading version...</div>;
if (error) return <div>Version unavailable</div>;
return (
<div>
<p>Data version: {versionInfo.commit.substring(0, 7)}</p>
<p>Updated: {new Date(versionInfo.date).toLocaleDateString()}</p>
<button onClick={refetch}>Refresh</button>
</div>
);
}
Display Variantsβ
Inline Variantβ
Compact text display suitable for footers or sidebars.
<VersionDisplay variant="inline" />
// Output: "Data v.abc1234 β’ Updated 2 hours ago"
Badge Variantβ
Pill-shaped badge with icon, perfect for headers or navigation.
<VersionDisplay variant="badge" />
// Output: [π v.abc1234]
Detailed Variantβ
Comprehensive view with all version information.
<VersionDisplay variant="detailed" showDetails={true} />
// Output: Card with commit, date, message, author, repository link
Best Practicesβ
1. Placementβ
- Footer: Use inline or badge variant
- Admin panels: Use detailed variant
- Headers: Use badge variant
- Tooltips: Wrap any variant with VersionTooltip
2. Refresh Intervalsβ
- Public pages: 5-10 minutes
- Admin pages: 1-2 minutes
- Real-time dashboards: 30 seconds
3. Error Handlingβ
- Always provide fallback UI
- Log errors for monitoring
- Show user-friendly messages
4. Performanceβ
- Use appropriate cache durations
- Implement stale-while-revalidate
- Avoid excessive API calls
Troubleshootingβ
Version Not Updatingβ
Issue: Version information doesn't refresh
Solution: Check refresh interval and cache settings
// Force immediate refresh
const { refetch } = useVersionInfo();
refetch();
API Errorsβ
Issue: /api/version returns errors
Solution: Verify environment variables and repository access
# Check environment variables
echo $DATA_REPOSITORY
echo $GH_TOKEN
# Test repository access
git ls-remote $DATA_REPOSITORY
Slow Loadingβ
Issue: Version component loads slowly
Solution: Optimize caching and reduce refresh frequency
<VersionDisplay
variant="badge"
refreshInterval={600000} // 10 minutes
/>
Advanced Featuresβ
Manual Sync Triggerβ
// app/api/version/sync/route.ts
export async function POST() {
await syncRepository();
return NextResponse.json({ success: true });
}
Version Change Notificationsβ
import { useVersionInfo } from "@/hooks/use-version-info";
import { useEffect } from "react";
export function VersionWatcher() {
const { versionInfo } = useVersionInfo();
useEffect(() => {
if (versionInfo) {
// Notify user of new version
console.log('New data version:', versionInfo.commit);
}
}, [versionInfo?.commit]);
return null;
}
Custom Formattingβ
import { useVersionInfo } from "@/hooks/use-version-info";
import { formatDistanceToNow } from "date-fns";
export function CustomVersion() {
const { versionInfo } = useVersionInfo();
return (
<div>
<span>v{versionInfo.commit.substring(0, 7)}</span>
<span>{formatDistanceToNow(new Date(versionInfo.date))} ago</span>
</div>
);
}
Next Stepsβ
- Testing - Test your implementation
- API Documentation - Learn about API docs
- Deployment - Deploy with version tracking