1. Enable Activity Logs in the Velt Console
- Go to the Activity Logs section in the Configurations section of the Velt Console and enable Activity Logs.
Activity Logs will not work if you do not enable this first.
2. Add the Activity Log Component
Add VeltActivityLog to render a pre-built, filterable timeline of all Velt and your custom app activities (comments, reactions, recorder, CRDT) grouped by calendar date.
React / Next.js
Other Frameworks
import { VeltActivityLog } from '@veltdev/react';
<VeltActivityLog darkMode={false} useDummyData={true} />
<velt-activity-log use-dummy-data="true"></velt-activity-log>
3. Create a Custom Activity
- Frontend API: Use
createActivity() to push your own events into the activity feed. Supply a displayMessageTemplate with {{variable}} placeholders and provide values in displayMessageTemplateData.
- Backend REST API: You can also use Add Activities API to create activities.
React / Next.js
Other Frameworks
Using Hook:import { useActivityUtils } from '@veltdev/react';
function CustomActivityButton() {
const activityElement = useActivityUtils();
const handleClick = async () => {
await activityElement?.createActivity({
featureType: 'custom',
actionType: 'custom',
targetEntityId: 'my-entity-id',
displayMessageTemplate: '{{actionUser.name}} deployed version {{version}}',
displayMessageTemplateData: { version: 'v2.3.1' },
});
};
return <button onClick={handleClick}>Create Activity</button>;
}
Using API:const activityElement = client.getActivityElement();
await activityElement.createActivity({
featureType: 'custom',
actionType: 'custom',
targetEntityId: 'annotation-id',
displayMessageTemplate: '{{actionUser.name}} escalated this to {{assignee.name}}',
displayMessageTemplateData: { assignee: { name: 'Alice' } },
});
const activityElement = Velt.getActivityElement();
await activityElement.createActivity({
featureType: 'custom',
actionType: 'custom',
targetEntityId: 'annotation-id',
displayMessageTemplate: '{{actionUser.name}} escalated this to {{assignee.name}}',
displayMessageTemplateData: { assignee: { name: 'Alice' } },
});
4. Subscribe to Activities
If you are using the prebuilt components, you can skip this step.
Call getAllActivities() to receive a real-time stream of activity records. The observable emits the full list whenever the feed changes.
React / Next.js
Other Frameworks
Using Hook:import { useAllActivities } from '@veltdev/react';
function ActivityFeed() {
const activities = useAllActivities();
if (activities === null) return <p>Loading...</p>;
if (activities.length === 0) return <p>No activities yet.</p>;
return (
<ul>
{activities.map((activity) => (
<li key={activity.id}>{activity.displayMessage}</li>
))}
</ul>
);
}
With filters:import { useAllActivities } from '@veltdev/react';
function DocumentActivityFeed({ documentId }: { documentId: string }) {
const activities = useAllActivities({
documentIds: [documentId],
featureTypes: ['comment', 'reaction'],
});
// ...
}
Using API:const activityElement = client.getActivityElement();
const subscription = activityElement.getAllActivities().subscribe((activities) => {
if (activities === null) return;
console.log(activities);
});
// Clean up when done
subscription?.unsubscribe();
const activityElement = Velt.getActivityElement();
const subscription = activityElement.getAllActivities().subscribe((activities) => {
if (activities === null) return;
console.log(activities.map((a) => a.displayMessage));
});
// Document-scoped with filters
const docSubscription = activityElement.getAllActivities({
documentIds: ['my-document-id'],
featureTypes: ['comment'],
}).subscribe((activities) => {
console.log(activities);
});
REST APIs
You can also manage activities server-side using the REST API:
- Get Activities — Retrieve activity records filtered by document, feature type, action type, or user.
- Add Activities — Create new activity records for custom or application-level events.
- Update Activities — Update existing activity records by ID.
- Delete Activities — Delete activity records by document, target entity, or specific IDs.