Overview
Velt supports self-hosting your comments and related data:- Comments can be stored on your own infrastructure, with only necessary identifiers on Velt servers.
- Velt Components automatically hydrate comment data in the frontend by fetching from your configured data provider.
- This gives you full control over comment data while maintaining all Velt collaboration features.
- This automatically also ensures that the in-app notifications content is not stored on Velt servers. The content is generated using the comments data in the frontend.
How does it work?
- When comments are created, updated, deleted or requested, the SDK uses your configured
CommentAnnotationDataProviderto handle storage and retrieval - The data provider implements
get,save, anddeletemethods to interact with your database - Velt handles the data mapping and realtime synchronization while delegating persistence of actual content to your infrastructure
- The data provider works at the Comment Annotation (Thread) level not at the individual Comment (Message) level.
- For write requests (save, delete), the operation is first performed on your database and only if we get a success response, the SDK will perform the operation on the Velt server. If the operation fails on your database, the SDK will not perform the operation on the Velt server.
- You can configure retries, timeouts, etc. for the data provider.
Implementation Approaches
You can implement comment self-hosting using either of these approaches:- Endpoint based: Provide endpoint URLs and let the SDK handle HTTP requests
- Function based: Implement
get,save, anddeletemethods yourself
| Feature | Function based | Endpoint based |
|---|---|---|
| Best For | Complex setups requiring middleware logic, dynamic headers, or transformation before sending | Standard REST APIs where you just need to pass the request “as-is” to the backend |
| Implementation | You write the fetch() or axios code | You provide the url string and headers object |
| Flexibility | High | Medium |
| Speed | Medium | High |
Endpoint based DataProvider
Instead of implementing custom methods, you can configure endpoints directly and let the SDK handle HTTP requests.getConfig
Config-based endpoint for fetching comments. The SDK automatically makes HTTP POST requests with the request body.- Type:
ResolverEndpointConfig - Request body format:
GetCommentResolverRequest - Response format:
ResolverResponse<Record<string, PartialCommentAnnotation>>
- React / Next.js
- Other Frameworks
saveConfig
Config-based endpoint for saving comments. The SDK automatically makes HTTP POST requests with the request body.- Type:
ResolverEndpointConfig - Request body format:
SaveCommentResolverRequest - Response format:
ResolverResponse<T>
- React / Next.js
- Other Frameworks
deleteConfig
Config-based endpoint for deleting comments. The SDK automatically makes HTTP POST requests with the request body.- Type:
ResolverEndpointConfig - Request body format:
DeleteCommentResolverRequest - Response format:
ResolverResponse<T>
- React / Next.js
- Other Frameworks
Endpoint based Complete Example
- React / Next.js
- Other Frameworks
Function based DataProvider
Implement custom methods to handle data operations yourself.get
Method to fetch comments from your database. On error we will retry.- Param:
GetCommentResolverRequest - Return:
Promise<ResolverResponse<Record<string, PartialCommentAnnotation>>>
- Frontend Example
- Backend Endpoint Example (MongoDB)
- Backend Endpoint Example (PostgreSQL)
save
Save comments to your database. Return a success or error response. On error we will retry.- Param:
SaveCommentResolverRequest- Note in the
SaveCommentResolverRequestobject, you will receive the event name that triggered the save.
- Note in the
- Return:
Promise<ResolverResponse<T>>
- Frontend Example
- Backend Endpoint Example (MongoDB)
- Backend Endpoint Example (PostgreSQL)
delete
Delete comments from your database. Return a success or error response. On error we will retry.- Param:
DeleteCommentResolverRequest - Return:
Promise<ResolverResponse<T>>
- Frontend Example
- Backend Endpoint Example (MongoDB)
- Backend Endpoint Example (PostgreSQL)
config
Configuration for the comment data provider.- Type:
ResolverConfig. Relevant properties:resolveTimeout: Timeout duration (in milliseconds) for resolver operationsgetRetryConfig:RetryConfig. Configure retry behavior for get operations.saveRetryConfig:RetryConfig. Configure retry behavior for save operations.deleteRetryConfig:RetryConfig. Configure retry behavior for delete operations.
Function based Complete Example
- React / Next.js
- Other Frameworks
Triggering Email Notifications when Self-Hosting
When you self-host content, use Webhooks to trigger emails from your own system:Enable relevant webhooks
Subscribe to comment-related events (e.g., user mentions, replies). See Webhooks.
Receive webhook and fetch content from your DB
Your server receives the webhook event. Use IDs from the payload (e.g.,
annotationId, commentId) to query your own comment and notification content from your database via your Data Provider.Assemble email content and recipients
Combine the webhook event context with the self-hosted content to build the subject, body, and list of recipients (e.g., mentioned users).
- Example Webhook Payload
- Example Notification Code (Node.js)
cURL
Sample Data
- Stored on your database
- Stored on Velt servers
Debugging
You can subscribe todataProvider events to monitor and debug get, save, and delete operations. The event includes a moduleName field that identifies which module triggered the resolver call, helping you trace data provider requests.
You can also use the Velt Chrome DevTools extension to inspect and debug your Velt implementation.
Type: CommentResolverModuleName
- React / Next.js
- Other Frameworks

