v3/goal_ui/docs/WIDGET-INTEGRATION.md
The RuFlo Research Widget is a standalone, embeddable component that brings Goal-Oriented Action Planning research capabilities to any website. It's fully self-contained with no external dependencies required on the host page.
Add this code to any HTML page:
<!-- 1. Add widget container -->
<div id="ruflo-research-widget-container"></div>
<!-- 2. Load widget files -->
<link rel="stylesheet" href="https://YOUR-DOMAIN/widget.css">
<script src="https://YOUR-DOMAIN/widget.js"></script>
That's it! The widget will automatically initialize.
<!-- Widget container -->
<div id="ruflo-research-widget-container"></div>
<!-- Configuration (optional) -->
<script>
window.RufloResearchWidgetConfig = {
primaryColor: "#8b5cf6",
accentColor: "#22c55e",
backgroundColor: "#1a1a1a",
cardBackgroundColor: "#262626",
textColor: "#ffffff",
fontFamily: "system-ui",
defaultGoal: "Research the latest advancements in quantum computing"
};
</script>
<!-- Load widget -->
<link rel="stylesheet" href="https://YOUR-DOMAIN/widget.css">
<script src="https://YOUR-DOMAIN/widget.js"></script>
All configuration options are optional. The widget will use sensible defaults.
window.RufloResearchWidgetConfig = {
// Colors (use hex format)
primaryColor: "#8b5cf6", // Main brand color
accentColor: "#22c55e", // Success/highlight color
backgroundColor: "#1a1a1a", // Page background
cardBackgroundColor: "#262626", // Card backgrounds
cardBorderColor: "#404040", // Card borders
textColor: "#ffffff", // Primary text
secondaryTextColor: "#a3a3a3", // Secondary text
successColor: "#22c55e", // Success indicators
// Content
title: "Goal-Oriented Action Planning",
description: "AI-powered research planning...",
brandName: "Your Brand",
defaultGoal: "Default research goal",
// Styling
fontFamily: "system-ui", // Font family
borderRadius: "0.5rem", // Border radius for cards
animationSpeed: "normal", // Animation speed: "slow", "normal", "fast"
cardSpacing: "1rem", // Space between cards
// Features
showMetrics: true, // Show step metrics
showStats: true, // Show statistics
compactMode: false, // Compact layout
enableAI: true, // Enable AI features
aiModel: "google/gemini-2.5-flash" // AI model to use
};
Use a custom container ID:
<div id="my-custom-container"></div>
<script>
window.addEventListener('load', function() {
if (window.RufloResearchWidget) {
window.RufloResearchWidget.init('my-custom-container');
}
});
</script>
The widget files are configured with proper CORS headers to work on any domain:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, OPTIONS
If your site uses CSP, add these directives:
<meta http-equiv="Content-Security-Policy"
content="script-src 'self' https://YOUR-DOMAIN;
style-src 'self' https://YOUR-DOMAIN 'unsafe-inline';">
To embed via iframe:
<iframe
src="https://YOUR-DOMAIN/widget-embed.html"
width="100%"
height="800"
frameborder="0"
style="border: none;">
</iframe>
The widget is fully responsive and mobile-friendly. It will automatically adapt to:
Disable auto-initialization and manually control when the widget loads:
// The widget auto-initializes by default
// To prevent this, load the widget script with defer
<script src="/widget.js" defer></script>
// Then manually initialize when ready
window.addEventListener('DOMContentLoaded', function() {
if (window.RufloResearchWidget) {
window.RufloResearchWidget.init('ruflo-research-widget-container');
}
});
Check the widget version:
console.log(window.RufloResearchWidget.version); // "1.0.0"
Load multiple widgets on the same page:
<div id="widget-1"></div>
<div id="widget-2"></div>
<script>
window.addEventListener('load', function() {
window.RufloResearchWidget.init('widget-1');
window.RufloResearchWidget.init('widget-2');
});
</script>
If you see CORS errors:
Access to script at 'https://your-domain/widget.js' from origin 'https://other-domain'
has been blocked by CORS policy
Solutions:
_headers file is deployed with proper CORS headersnetlify.toml is configured correctlyIf widget styling looks broken:
!important to widget container stylesFor large pages or slow connections:
defer or async<?php
// Add to your theme's functions.php
function add_goap_widget() {
?>
<div id="ruflo-research-widget-container"></div>
<script>
window.RufloResearchWidgetConfig = {
primaryColor: "<?php echo get_theme_mod('primary_color', '#8b5cf6'); ?>",
defaultGoal: "<?php echo get_option('goap_default_goal'); ?>"
};
</script>
<link rel="stylesheet" href="https://YOUR-DOMAIN/widget.css">
<script src="https://YOUR-DOMAIN/widget.js"></script>
<?php
}
add_action('wp_footer', 'add_goap_widget');
?>
import { useEffect } from 'react';
export default function RufloResearchWidget() {
useEffect(() => {
// Load widget script
const script = document.createElement('script');
script.src = 'https://YOUR-DOMAIN/widget.js';
script.async = true;
document.body.appendChild(script);
// Load widget CSS
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://YOUR-DOMAIN/widget.css';
document.head.appendChild(link);
return () => {
document.body.removeChild(script);
document.head.removeChild(link);
};
}, []);
return <div id="ruflo-research-widget-container" />;
}
<template>
<div id="ruflo-research-widget-container"></div>
</template>
<script>
export default {
mounted() {
// Set configuration
window.RufloResearchWidgetConfig = {
primaryColor: this.$root.theme.primaryColor
};
// Load widget
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://YOUR-DOMAIN/widget.css';
document.head.appendChild(link);
const script = document.createElement('script');
script.src = 'https://YOUR-DOMAIN/widget.js';
document.body.appendChild(script);
}
}
</script>
To build the widget from source:
# Install dependencies
npm install
# Build widget
npm run build:widget
# Output will be in dist/widget.js and dist/widget.css
MIT License - See LICENSE file for details