Custom Reference Integration¶
Many deployments need to display a local catalog of references, highlight citations as authors select them, and sync back to an external service. This guide distills the moving parts so you can recreate the pattern in your own UI.
Data Flow¶
- Host app owns the reference list (from your API, CSL store, etc.).
- Editor emits events (
editor-change,editor-selection-change) whenever the document or selection changes. - Sidebar components render references, highlight matches, and dispatch drag/drop or click events back to the editor.
Step-by-Step¶
1. Render Your Reference Panel¶
Create a list component (plain DOM or framework) that exposes two methods:
render(references: Array<{ id: string; rawCitation: string; mimeType?: string }>)highlight(ids: string[])
Start with static markup and evolve it as needed; no special helpers are required from the package.
2. Listen for Document Updates¶
editor.addEventListener('editor-change', (event) => {
const { doc, references } = event.detail;
latestDoc = doc;
panel.render(references ?? resolveReferences(doc));
});
resolveReferences is your hook to fetch or derive metadata (CSL JSON, raw citations, etc.) when you do not supply a references array alongside the snapshot.
3. Highlight References Based on Selection¶
Listen to editor-selection-change, extract citation ids from the selection snapshot, and pass them into your panel:
editor.addEventListener('editor-selection-change', (event) => {
const ids = extractCitationIds(event.detail);
panel.highlight(ids);
});
For a complete reference list example (including drag payloads), see sciflow-reference-list.
4. Support Drag-and-Drop Insertion¶
Use a consistent drag payload so the citation feature can consume it automatically:
transfer.setData('application/x-sciflow-reference', 'sidebar');
transfer.setData('application/json', JSON.stringify({
type: 'reference',
id: reference.id,
text: reference.rawCitation,
}));
The citation feature automatically consumes this payload via the drop handler in packages/editor/core/src/lib/features/citation/index.ts, calling runInsertCitation. Reuse the same MIME types so no extra work is required in the editor.
Optional: Programmatic Insertion¶
If you prefer buttons or menus to drag-and-drop:
const insertCitation = editor.commands?.commands?.insertCitation;
if (insertCitation) {
insertCitation({
items: [{ id: 'reference-1' }],
text: '[1]',
style: 'apa',
});
}
Async lookups
Resolve metadata (authors, titles) before calling the command. The editor only stores what you send in text plus whatever you include in the node attributes.