@driveloader/react
v1.2.0
Published
The definitive React library for loading, caching, and resolving Google Drive hosted images.
Maintainers
Readme
@driveloader/react
The definitive React library for loading, caching, resolving, and diagnosing Google Drive hosted images and public folders.
🌟 Why @driveloader/react?
Google Drive link sharing is notoriously tricky. Standard drive.google.com/file/d/... or open?id=... URLs fail inside <img src="..." /> tags because they are HTML viewing pages rather than direct image file binaries.
@driveloader/react completely solves this problem for both single images and entire public Google Drive folders.
Simply pass any Google Drive link or file ID to <DriveImage src="..." /> or load entire public folders via useDriveFolder() / <DriveGallery folderUrl="..." apiKey="..." />.
🚀 Key Features
- ✅ Google Drive Images: Render Google Drive images with skeletons, lazy loading, and failover endpoints.
- ✅ Google Drive Videos: Stream Google Drive videos using
<DriveVideo />with poster thumbnails and metadata extraction. - ✅ Mixed Media Galleries: Responsive
<DriveGallery />automatically renders images and videos side-by-side. - 🧠 Endpoint Learning: Automatically remembers working CDN endpoints per file ID and prioritizes them in future resolutions.
- 📁 Public Folder Loading: Load all media assets (images & videos) from a public Google Drive folder using official Google Drive API v3.
- 🔄 Pagination & Sorting: Support for
loadMore(), page tokens, sorting (name,createdTime,modifiedTime), and extension filtering (['jpg', 'png', 'mp4']). - ⚡ Request Coalescing: Prevents duplicate network requests when rendering multiple instances of the same asset across your app.
- 📦 Batch Resolution: Concurrently resolves arrays of URLs with
resolveDriveImages()and worker queue controls. - 🔍 Diagnostics API:
analyzeDriveUrl(url)inspects link validity, format variants, TTL, and actionable recommendations. - 📊 Cache Metrics: Real-time stats (
getCacheStats()) on hit rates, active requests, and memory usage. - 🛡️ Typed Errors: Actionable custom error hierarchy (
InvalidDriveUrlError,InvalidVideoError,VideoResolutionError,PrivateFileError,ResolutionFailedError). - ⚡ Zero Runtime Dependencies: Ultra-lightweight and tree-shakeable.
⚡ Quick Start
Single Image Component
import { DriveImage } from '@driveloader/react';
import '@driveloader/react/styles.css';
export function ProfileAvatar() {
return (
<DriveImage
src="https://drive.google.com/file/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs/view"
alt="User Profile"
width={120}
height={120}
fade={true}
/>
);
}Single Video Component (DriveVideo)
import { DriveVideo } from "@driveloader/react";
import '@driveloader/react/styles.css';
export function VideoPlayer({ driveUrl }: { driveUrl: string }) {
return (
<DriveVideo
src={driveUrl}
controls
autoPlay={false}
preload="metadata"
width={640}
height={360}
/>
);
}Video Resolution Hook (useDriveVideo)
import { useDriveVideo } from "@driveloader/react";
function VideoDetails({ driveUrl }: { driveUrl: string }) {
const { videoUrl, loading, error, metadata, thumbnailUrl } = useDriveVideo(driveUrl);
if (loading) return <div>Resolving Google Drive Video...</div>;
if (error) return <div>Failed to load video: {error.message}</div>;
return (
<div>
<video src={videoUrl!} controls poster={thumbnailUrl || undefined} />
<p>Duration: {metadata?.duration}s | Dimensions: {metadata?.width}x{metadata?.height}</p>
</div>
);
}📁 Loading Public Folders (useDriveFolder)
import { useDriveFolder, DriveImage } from '@driveloader/react';
function FolderGallery({ folderUrl, apiKey }: { folderUrl: string; apiKey: string }) {
const { folder, assets, loading, error, loadMore, hasMore } = useDriveFolder({
folderUrl,
apiKey,
mediaTypes: ['image'],
extensions: ['jpg', 'png', 'webp'],
orderBy: 'createdTime desc',
pageSize: 20,
});
if (loading && assets.length === 0) return <div>Loading Google Drive folder...</div>;
if (error) return <div>Failed to load folder: {error.message}</div>;
return (
<div>
<h3>{folder?.name}</h3>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '1rem' }}>
{assets.map((asset) => (
<DriveImage key={asset.id} src={asset.resolvedUrl} alt={asset.name} />
))}
</div>
{hasMore && <button onClick={loadMore}>Load More</button>}
</div>
);
}🖼️ Automatic Gallery Folder Mode (DriveGallery)
import { DriveGallery } from '@driveloader/react';
export function EventPhotoGallery() {
return (
<DriveGallery
folderUrl="https://drive.google.com/drive/folders/1a2B3c4D5e6F7g8H9i0J"
apiKey="YOUR_GOOGLE_DRIVE_API_KEY"
columns={{ sm: 1, md: 2, lg: 4 }}
gap="1.5rem"
orderBy="name"
/>
);
}📦 Batch Resolution (resolveDriveImages)
import { resolveDriveImages } from '@driveloader/react';
const { results, successful, failed } = await resolveDriveImages([
'https://drive.google.com/file/d/ID_1/view',
'https://drive.google.com/open?id=ID_2',
], { concurrency: 4 });🔍 Link Diagnostics API (analyzeDriveUrl)
import { analyzeDriveUrl } from '@driveloader/react';
const info = analyzeDriveUrl('https://drive.google.com/file/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs/view');
console.log(info.valid); // true
console.log(info.fileId); // '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs'
console.log(info.detectedFormat); // 'file_d'
console.log(info.recommendations); // ['Verify in Google Drive that access is set to Anyone with the link...']🔑 Google Drive API Key Setup for Folders
- Go to Google Cloud Console → APIs & Services → Credentials.
- Click Create Credentials → API Key.
- Go to API Library → Enable Google Drive API.
- Restrict your API key HTTP Referrers to your web application domain.
🤝 Contributing
Contributions are welcome! Please check out our CONTRIBUTING.md guide before submitting pull requests.
📄 License
MIT © DriveLoader Contributors
