Components
bio-journal
<bio-journal>
A free-text journal widget that lets users write daily reflections in response to an optional prompt. Records each save as a pro.journal Observation on the shared timeline, with an optional history view of prior entries.
<bio-journal></bio-journal>How It Works
When <bio-journal> receives context from a parent <bio-provider>:
- Resolves configuration — in profile-driven mode, reads the prompt and status from the SDK config's
journalsection; in static mode, uses attribute defaults - Loads existing entry — fetches today's
pro.journalobservation (if any) and pre-populates the textarea so the user can edit - Renders the prompt — shows the configured prompt above the textarea
- Saves on submit — posts to
POST /api/v1/xusers/{id}/observations/journalwithtext,prompt,day, andepisode_id; stores the response asvalue_string - History view (optional) — when
show-historyis set, exposes a "History" button that loads the most recent 20 entries
Modes
Profile-Driven Mode
Omit all attributes. The widget reads its configuration from the program's spec.sdk.journal section:
<bio-journal></bio-journal>The profile defines:
prompt— text shown above the textareaschedule—"daily"or"weekly"show_history— whether the History button is enabled
Static Mode
Pass configuration directly:
<bio-journal
prompt="What's on your mind today?"
show-history
episode-id="ep_abc123"
day="3">
</bio-journal>Attributes
| Attribute | Type | Required | Description |
|---|---|---|---|
prompt | string | No | Prompt text shown above the textarea. Falls back to the SDK config prompt. |
show-history | boolean | No | When present, renders a History button that loads prior entries. |
episode-id | string | No | Episode ID. Falls back to the episode resolved by <bio-provider>. |
day | number | No | Day index within the episode. Falls back to the episode's current day. |
Events
| Event | Detail | Description |
|---|---|---|
anybio:journal:save | { text, observationId, day, episodeId } | Fired after a successful save. |
CSS Classes
| Class | Element |
|---|---|
.bio-journal | Root container |
.bio-journal-prompt | Prompt text above the textarea |
.bio-journal-textarea | Free-text input |
.bio-journal-footer | Footer row with status and action buttons |
.bio-journal-status | "Saved 10:30 AM" status text |
.bio-journal-saved | Saved-timestamp span |
.bio-journal-actions | Button container |
.bio-journal-history-btn | History toggle button |
.bio-journal-save-btn | Save button |
.bio-journal-history | History panel container |
.bio-journal-history-loading | Loading state inside the history panel |
.bio-journal-history-empty | Empty state inside the history panel |
.bio-journal-history-entry | Single prior entry |
.bio-journal-history-meta | Day + date row for an entry |
.bio-journal-history-text | Entry body |
Code Examples
Profile-Driven
<bio-provider
api-key="org_your_key"
project-key="proj_your_key"
xuser-id="user-123">
<h3>Daily Reflection</h3>
<bio-journal></bio-journal>
</bio-provider>With History and Event Handling
<bio-journal
prompt="What went well today? What was hard?"
show-history>
</bio-journal>
<script>
document.addEventListener('anybio:journal:save', (e) => {
const { text, observationId, day } = e.detail;
console.log(`Day ${day} entry saved: ${observationId}`);
showToast('Journal saved');
});
</script>Custom Styling
bio-journal {
--bio-journal-textarea-min-height: 8rem;
}
.bio-journal-textarea {
font-family: 'Georgia', serif;
font-size: 1.05rem;
}Observation Shape
Each save produces an Observation with:
biosignal_name:pro.journalvalue_string: the entry texteffective_datetime: save timemetadata.widget:bio-journalmetadata.day: the episode day (when available)metadata.prompt: the prompt that was shown (when available)
Agents can query these via GET /api/v1/observations?xuser_id=...&biosignal_name=pro.journal to surface themes or trigger follow-up check-ins.