Vyuh Framework
Build Modular, Scalable, CMS-driven Flutter Apps
Vyuh Content Provider for Sanity π
A powerful content provider plugin that seamlessly integrates Sanity.io with the Vyuh framework. This plugin enables your Vyuh application to fetch, cache, and manage content from Sanity.io with minimal configuration.
Features β¨
-
Content Management
- Fetch single or multiple documents
- Support for all Sanity content types
- Automatic content type mapping
- Built-in caching with configurable duration
-
Asset Support
- Image assets with transformations
- File assets with metadata
- Reference handling
- Asset caching
-
Routing Integration
- Automatic route generation from content
- Support for Vyuh framework schema
- Dynamic route parameters
- Nested route handling
-
Performance
- Efficient content caching
- CDN support
- Optimized network requests
- Parallel content fetching
Installation π¦
Add this to your package's pubspec.yaml file:
dependencies:
vyuh_plugin_content_provider_sanity: ^1.0.0
Usage π‘
Basic Setup
Create and configure the Sanity content provider:
import 'package:vyuh_core/vyuh_core.dart' as vc;
import 'package:sanity_client/sanity_client.dart';
import 'package:vyuh_plugin_content_provider_sanity/vyuh_plugin_content_provider_sanity.dart';
final contentProvider = SanityContentProvider.withConfig(
config: SanityConfig(
projectId: '<project-id>',
dataset: 'production',
perspective: Perspective.published, // or previewDrafts for draft content
useCdn: true, // enable CDN for better performance
),
cacheDuration: const Duration(minutes: 5),
);
void main() async {
vc.runApp(
features: () => [
// your features here
],
plugins: [
contentProvider,
// other plugins
],
);
}
Fetching Content
// Fetch a single document
final post = await contentProvider.fetchSingle<Post>(
'*[_type == "post" && _id == $id][0]',
fromJson: Post.fromJson,
queryParams: {'id': 'post-123'},
);
// Fetch multiple documents
final posts = await contentProvider.fetchMultiple<Post>(
'*[_type == "post" && category == $category]',
fromJson: Post.fromJson,
queryParams: {'category': 'tech'},
);
// Fetch by ID
final author = await contentProvider.fetchById<Author>(
'author-123',
fromJson: Author.fromJson,
);
Working with Assets
// Get an ImageProvider for use in Image widget
final imageProvider = contentProvider.image(
ImageReference(
asset: Asset(ref: 'image-Tb9Ew8CXIwaY6R1kjMvI0uRR-2000x3000-jpg'),
),
width: 800,
height: 600,
devicePixelRatio: 2,
quality: 80,
format: 'webp',
);
// Use in an Image widget
if (imageProvider != null) {
Image(image: imageProvider)
}
// Get a file URL
final fileUrl = contentProvider.fileUrl(fileRef);
Route Handling
// Fetch route by path
final route = await contentProvider.fetchRoute(
path: '/blog/my-post',
);
// Fetch route by ID
final route = await contentProvider.fetchRoute(
routeId: 'route-123',
);
if (route != null) {
// Handle route content
}
Live Query Integration NEW β¨
SanityContentProvider now includes support for the LiveContentProvider API.
It offers real-time updates for your Sanity content, allowing your app to stay
in sync with your dataset.
The API is almost identical with the standard
ContentProvider, barring the fact that the live API returns aStream<T?>instead of aFuture<T?>.
Here are examples of how to use the live query methods:
// Create a LiveProvider instance
final liveProvider = SanityContentProvider(
projectId: 'your-project-id',
dataset: 'your-dataset',
useCdn: true,
perspective: 'published',
).live; // Notice the call to get the LiveContentProvider instance
// Fetch real-time updates for a single document
final singleStream = liveProvider.fetchSingle<Post>(
'*[_type == "post" && _id == $id][0]',
fromJson: Post.fromJson,
queryParams: {'id': 'post-123'},
);
singleStream.listen((post) {
// Handle updated post
});
// Fetch real-time updates for multiple documents
final multipleStream = liveProvider.fetchMultiple<Post>(
'*[_type == "post" && category == $category]',
fromJson: Post.fromJson,
queryParams: {'category': 'tech'},
);
multipleStream.listen((posts) {
// Handle updated list of posts
});
// Fetch real-time updates by ID
final idStream = liveProvider.fetchById<Author>(
'author-123',
fromJson: Author.fromJson,
);
idStream.listen((author) {
// Handle updated author
});
// Use StreamBuilder in your widget tree
StreamBuilder<Post>(
stream: singleStream,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data!.title);
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
}
return CircularProgressIndicator();
},
);
Configuration π§
The content provider can be configured with various options:
final provider = SanityContentProvider.withConfig(
config: SanityConfig(
projectId: '<project-id>',
dataset: 'production',
// Content delivery options
useCdn: true, // Use CDN for better performance
perspective: Perspective.published, // Content perspective
// Cache configuration
cacheDuration: Duration(minutes: 5),
// Optional authentication
token: '<your-token>', // For accessing private datasets
),
// Additional options
debug: true, // Enable debug logging
retryOptions: RetryOptions( // Configure retry behavior
maxAttempts: 3,
delayFactor: Duration(seconds: 1),
),
);
Error Handling π¨
The provider includes proper error handling for various scenarios:
try {
final post = await contentProvider.fetchSingle<Post>(
'*[_type == "post" && _id == $id][0]',
fromJson: Post.fromJson,
queryParams: {'id': 'post-123'},
);
// Handle post
} on InvalidResultTypeException catch (e) {
print('Type mismatch: Expected ${e.expectedType}, got ${e.actualType}');
} on SanityError catch (e) {
print('Sanity API error: ${e.message}');
} on Exception catch (e) {
print('Unexpected error: $e');
}
// When fetching route
try {
final route = await contentProvider.fetchRoute(path: '/blog/my-post');
if (route == null) {
print('Route not found');
return;
}
// Handle route
} on SanityError catch (e) {
print('Error fetching route: ${e.message}');
}
Contributing π€
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
Learn More π
- Visit docs.vyuh.tech for detailed documentation
- Check out the GitHub repository for source code
- Report issues on the issue tracker
- Learn more about Sanity.io
Made with β€οΈ by Vyuh