Volpe Plugin Communication Protocol
Overview
This document defines the standard protocol for third-party plugins to integrate with the Volpe reader. The protocol enables plugins to receive reading context and respond to reader events through a secure iframe-based communication system.
Architecture
Plugins are embedded as iframes within Volpe's ReaderSidebarPlugin component. Communication occurs via PostMessage API with security measures including nonce validation and origin checking.
Plugin Requirements
Iframe Constraints
- Maximum width: 420px (mobile-first design)
- Recommended dimensions: 420px × 600px
- Minimum supported: 320px × 480px
URL Parameters
Plugins receive authentication and security parameters via URL:
https://plugin.example.com/?token=<JWT_TOKEN>&nonce=<NONCE>
JWT Structure
The JWT token contains context about the user and publication:
{
"iss": "farfalla",
"aud": "reader-plugin",
"sub": "user-id",
"iat": 1746388157,
"exp": 1746474557,
"payload": {
"tenantId": 67,
"tenantUrl": "https://tenant.example.com",
"userId": 12345,
"userLang": "en",
"publicationId": 112589996700258
}
}
PostMessage Protocol
Message Structure
All Volpe-to-plugin messages follow this structure:
{
type: "event",
name: String, // Event name: "init", "page-change", "theme-change"
id: String, // Unique message ID (UUID v7)
timestamp: Number, // Unix timestamp
nonce: String, // Must match URL nonce parameter
payload: Object // Event-specific data
}
Events
1. Init Event
Sent once after the plugin iframe loads:
{
type: "event",
name: "init",
id: "uuid-v7",
timestamp: Date.now(),
nonce: "security-nonce",
payload: {
currentPages: [1], // Current page(s) displayed
totalPages: 150, // Total publication pages
contentType: "pdf", // "pdf", "epub", or "audio"
darkMode: false // Theme state
}
}
2. Page Change Event
Sent when the user navigates:
{
type: "event",
name: "page-change",
id: "uuid-v7",
timestamp: Date.now(),
nonce: "security-nonce",
payload: {
currentPages: [5] // or [5, 6] for double-page spread
}
}
3. Theme Change Event
Sent when the user changes theme:
{
type: "event",
name: "theme-change",
id: "uuid-v7",
timestamp: Date.now(),
nonce: "security-nonce",
payload: {
darkMode: true // or false for light mode
}
}
Security Requirements
- Nonce Validation: Plugins MUST validate that the message nonce matches the URL parameter
- Origin Checking: Always verify
event.originbefore processing messages - No Outbound Messages: Plugins should NOT send messages back to Volpe (one-way communication)
- Target Origin: In production, use specific origin instead of "*"
Implementation Example
// Plugin initialization
const urlParams = new URLSearchParams(window.location.search);
const nonce = urlParams.get('nonce');
const token = urlParams.get('token');
// Listen for Volpe messages
window.addEventListener('message', (event) => {
// Validate origin (replace with actual Volpe origin)
if (event.origin !== 'https://reader.example.com') return;
// Validate message structure
if (!event.data || event.data.type !== 'event') return;
// Validate nonce
if (event.data.nonce !== nonce) return;
// Handle events
switch (event.data.name) {
case 'init':
initializePlugin(event.data.payload);
break;
case 'page-change':
updateContext(event.data.payload.currentPages);
break;
case 'theme-change':
updateTheme(event.data.payload.darkMode);
break;
}
});
Known Implementations
- Vito AI Assistant: AI-powered reading assistant that provides summaries, assessments, and Q&A
- Additional plugins can be developed following this protocol
Best Practices
- Mobile-First Design: Design for 420px width constraint
- Performance: Minimize resource usage to maintain reader performance
- Accessibility: Follow WCAG guidelines for plugin content
- Error Handling: Gracefully handle missing/invalid JWT or communication failures
- Theme Support: Respect user's theme preference for visual consistency