Advanced Integration
Advanced integration patterns and techniques for power users who need complete control over the IndexFox search widget behavior and appearance.
Always-Visible Widget (No Bubble)
For websites that want the search interface to be permanently visible without requiring user interaction, use the custom integration mode with auto-opening:
<script>
// Configure the widget BEFORE loading the script
window.IndexfoxConfig = {
integration: 'custom', // No bubble - custom integration
containerStyles: { // Customize the overlay container
position: 'fixed',
top: '0',
left: '0',
width: '100%',
height: '100%',
zIndex: '999999',
display: 'block', // Always visible instead of 'none'
background: 'transparent' // No overlay background
},
iframeStyles: { // Customize the iframe position/size
position: 'fixed', // Fixed positioning
top: '20px', // Distance from top
right: '20px', // Distance from right
width: '400px', // Width of the widget
height: '600px', // Height of the widget
border: 'none',
borderRadius: '16px',
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
background: 'white',
transform: 'none' // Remove centering transform
}
};
// Set your website ID and configuration BEFORE loading script
(function(d, w) {
// Set configuration first
w.IndexfoxConfig = {
integration: 'custom', // No bubble - custom integration
containerStyles: { // Customize the overlay container
position: 'fixed',
top: '0',
left: '0',
width: '100%',
height: '100%',
zIndex: '999999',
display: 'block', // Always visible instead of 'none'
background: 'transparent' // No overlay background
},
iframeStyles: { // Customize the iframe position/size
position: 'fixed', // Fixed positioning
top: '20px', // Distance from top
right: '20px', // Distance from right
width: '400px', // Width of the widget
height: '600px', // Height of the widget
border: 'none',
borderRadius: '16px',
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)',
background: 'white',
transform: 'none' // Remove centering transform
}
};
// Set website ID
w.IndexfoxID = 'your-website-id';
// Load script
var s = d.createElement('script');
s.async = true;
s.src = 'https://widget.indexfox.ai/indexfox.js';
if (d.head) d.head.appendChild(s);
})(document, window);
// Auto-open on page load
document.addEventListener('DOMContentLoaded', function() {
setTimeout(function() {
if (window.indexfox) {
window.indexfox.open();
}
}, 500);
});
</script>Container-Based Integration
Embed the search widget inside a specific container on your page instead of floating:
<!-- Your container where you want the widget -->
<div id="my-search-container" style="width: 100%; height: 500px; border: 1px solid #ddd; border-radius: 8px;"></div>
<script>
(function(d, w) {
// Set configuration first
w.IndexfoxConfig = {
integration: 'custom',
containerId: 'my-search-container', // Use your container ID
containerStyles: {
position: 'relative', // Relative positioning within your container
top: '0',
left: '0',
width: '100%',
height: '100%',
zIndex: '1',
display: 'block', // Always visible
background: 'transparent'
},
iframeStyles: {
position: 'absolute',
top: '0',
left: '0',
width: '100%',
height: '100%',
border: 'none',
borderRadius: '8px',
background: 'white',
transform: 'none'
}
};
// Set website ID
w.IndexfoxID = 'your-website-id';
// Load script
var s = d.createElement('script');
s.async = true;
s.src = 'https://widget.indexfox.ai/indexfox.js';
if (d.head) d.head.appendChild(s);
})(document, window);
// Auto-open when ready
document.addEventListener('DOMContentLoaded', function() {
setTimeout(function() {
if (window.indexfox) {
window.indexfox.open();
}
}, 500);
});
</script>Advanced CSS Customization
Override the widget's appearance with custom CSS variables and styles:
:root {
/* Primary colors */
--indexfox-primary-color: #667eea;
--indexfox-primary-hover: #5a67d8;
--indexfox-primary-light: #e6f3ff;
/* Background colors */
--indexfox-background: #ffffff;
--indexfox-background-secondary: #f7fafc;
--indexfox-background-hover: #edf2f7;
/* Text colors */
--indexfox-text-primary: #2d3748;
--indexfox-text-secondary: #718096;
--indexfox-text-muted: #a0aec0;
/* Border and spacing */
--indexfox-border-color: #e2e8f0;
--indexfox-border-radius: 12px;
--indexfox-shadow: 0 10px 40px rgba(0, 0, 0, 0.1);
--indexfox-spacing: 16px;
/* Typography */
--indexfox-font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
--indexfox-font-size: 14px;
--indexfox-line-height: 1.5;
/* Animation */
--indexfox-transition: all 0.2s ease;
}
/* Custom styles for specific elements */
.indexfox-container {
font-family: var(--indexfox-font-family) !important;
}
.indexfox-input {
border-radius: var(--indexfox-border-radius) !important;
border-color: var(--indexfox-border-color) !important;
}
.indexfox-result:hover {
background-color: var(--indexfox-background-hover) !important;
}Event Handling and Analytics
Listen to widget events for analytics tracking and custom functionality:
// Widget lifecycle events
window.addEventListener('indexfox:loaded', function() {
console.log('IndexFox widget loaded successfully');
// Initialize your custom functionality
});
window.addEventListener('indexfox:open', function() {
console.log('Search interface opened');
// Google Analytics 4
gtag('event', 'search_opened', {
event_category: 'engagement',
event_label: 'indexfox_widget'
});
// Custom analytics
analytics.track('Search Opened', {
source: 'indexfox_widget',
timestamp: new Date().toISOString()
});
});
window.addEventListener('indexfox:search', function(event) {
const query = event.detail.query;
const resultsCount = event.detail.resultsCount;
console.log('User searched for:', query, 'Results:', resultsCount);
// Track search queries
gtag('event', 'search', {
search_term: query,
results_count: resultsCount
});
// Custom search analytics
analytics.track('Search Query', {
query: query,
results_count: resultsCount,
source: 'indexfox_widget'
});
});
window.addEventListener('indexfox:result_click', function(event) {
const result = event.detail;
console.log('User clicked result:', result.title, result.url);
// Track result clicks
gtag('event', 'select_content', {
content_type: 'search_result',
item_id: result.url,
content_title: result.title
});
});
window.addEventListener('indexfox:close', function() {
console.log('Search interface closed');
gtag('event', 'search_closed', {
event_category: 'engagement'
});
});
// Error handling
window.addEventListener('indexfox:error', function(event) {
console.error('IndexFox widget error:', event.detail);
// Track errors for debugging
gtag('event', 'exception', {
description: 'IndexFox widget error: ' + event.detail.message,
fatal: false
});
});Responsive Configuration
Adapt the widget configuration based on screen size and device capabilities:
function getResponsiveConfig() {
const isMobile = window.innerWidth < 768;
const isTablet = window.innerWidth >= 768 && window.innerWidth < 1024;
const isDesktop = window.innerWidth >= 1024;
if (isMobile) {
return {
integration: 'bubble',
type: 'compact',
position: 'bottom-right',
iframeStyles: {
width: '100vw',
height: '100vh',
top: '0',
left: '0',
borderRadius: '0'
}
};
} else if (isTablet) {
return {
integration: 'bubble',
type: 'wide',
position: 'bottom-right',
iframeStyles: {
width: '500px',
height: '600px'
}
};
} else {
return {
integration: 'custom',
containerStyles: {
position: 'fixed',
top: '0',
right: '0',
width: '400px',
height: '100vh',
zIndex: '999999',
display: 'block',
background: 'transparent'
}
};
}
}
// Set responsive configuration
window.IndexfoxConfig = getResponsiveConfig();
// Update configuration on resize
window.addEventListener('resize', function() {
if (window.indexfox) {
window.indexfox.updateConfig(getResponsiveConfig());
}
});Dynamic Configuration Updates
Update widget configuration dynamically based on user preferences or application state:
// Theme switching
function switchTheme(theme) {
const themeConfigs = {
light: {
color: '#2563eb',
containerStyles: {
background: 'rgba(255, 255, 255, 0.95)'
}
},
dark: {
color: '#60a5fa',
containerStyles: {
background: 'rgba(17, 24, 39, 0.95)'
}
},
brand: {
color: '#7c3aed',
containerStyles: {
background: 'rgba(139, 92, 246, 0.1)'
}
}
};
if (window.indexfox && themeConfigs[theme]) {
window.indexfox.updateConfig(themeConfigs[theme]);
}
}
// User preference based configuration
function updateConfigForUser(userPreferences) {
const config = {
triggerKey: userPreferences.searchKey || 'k',
triggerModifier: userPreferences.searchModifier || 'Meta',
type: userPreferences.compactMode ? 'compact' : 'wide'
};
if (window.indexfox) {
window.indexfox.updateConfig(config);
}
}
// Language-specific configuration
function setLanguageConfig(language) {
const languageConfigs = {
'en': { placeholder: 'Search...' },
'es': { placeholder: 'Buscar...' },
'fr': { placeholder: 'Rechercher...' },
'de': { placeholder: 'Suchen...' }
};
if (window.indexfox && languageConfigs[language]) {
window.indexfox.updateConfig(languageConfigs[language]);
}
}Complete Integration Example
Here's a complete example combining multiple advanced features:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Advanced IndexFox Integration</title>
<style>
/* Custom widget styling */
:root {
--indexfox-primary-color: #667eea;
--indexfox-border-radius: 12px;
--indexfox-shadow: 0 20px 60px rgba(0, 0, 0, 0.15);
}
.search-trigger {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 12px 24px;
border-radius: 25px;
cursor: pointer;
font-weight: 600;
transition: transform 0.2s;
}
.search-trigger:hover {
transform: translateY(-2px);
}
#search-container {
width: 100%;
height: 500px;
border: 1px solid #e2e8f0;
border-radius: 12px;
margin: 20px 0;
}
</style>
</head>
<body>
<h1>My Website with Advanced Search</h1>
<!-- Custom search trigger -->
<button class="search-trigger" onclick="openSearch()">
🔍 Search Our Site
</button>
<!-- Container for embedded search -->
<div id="search-container"></div>
<script>
// Load widget using the exact pattern
(function(d, w) {
// Set configuration first
w.IndexfoxConfig = {
integration: 'custom',
containerId: 'search-container',
type: window.innerWidth < 768 ? 'compact' : 'wide',
color: '#667eea',
triggerKey: 'k',
triggerModifier: 'Meta',
containerStyles: {
position: 'relative',
width: '100%',
height: '100%',
display: 'block',
background: 'transparent'
},
iframeStyles: {
position: 'absolute',
top: '0',
left: '0',
width: '100%',
height: '100%',
border: 'none',
borderRadius: '12px',
background: 'white'
}
};
// Set website ID
w.IndexfoxID = 'your-website-id';
var s = d.createElement('script');
s.async = true;
s.src = 'https://widget.indexfox.ai/indexfox.js';
s.onload = function() {
console.log('IndexFox widget loaded');
// Auto-open after load
setTimeout(() => {
if (w.indexfox) {
w.indexfox.open();
}
}, 500);
};
if (d.head) d.head.appendChild(s);
})(document, window);
// Custom functions
function openSearch() {
if (window.indexfox) {
window.indexfox.open();
}
}
// Event listeners
window.addEventListener('indexfox:search', function(event) {
console.log('Search:', event.detail.query);
// Your analytics code here
});
window.addEventListener('indexfox:result_click', function(event) {
console.log('Result clicked:', event.detail.title);
// Track clicks
});
// Responsive updates
window.addEventListener('resize', function() {
if (window.indexfox) {
const newType = window.innerWidth < 768 ? 'compact' : 'wide';
window.indexfox.updateConfig({ type: newType });
}
});
</script>
</body>
</html>Troubleshooting
Widget Not Loading
Problem: Widget script fails to load or initialize
Solutions:
- Check that
IndexfoxIDis set before script loads - Verify script URL is correct and accessible
- Check browser console for JavaScript errors
- Ensure no ad blockers are interfering
No Search Results
Problem: Widget loads but shows "No results found"
Solutions:
- Verify
IndexfoxIDmatches your dashboard - Check that your website has been crawled
- Ensure website status is "Active" in dashboard
- Wait for initial crawling to complete (can take 24-48 hours)
Styling Issues
Problem: Widget doesn't match your site design
Solutions:
- Use CSS variables to override default styles
- Set
colorin IndexfoxConfig - Adjust
iframeStylesfor positioning - Use
!importantfor stubborn style overrides
Mobile Issues
Problem: Widget doesn't work well on mobile
Solutions:
- Use
type: 'compact'for mobile - Set responsive
iframeStyles - Test on actual devices, not just browser dev tools
- Consider different configs for mobile vs desktop
⚠️ Important Notes
- IndexfoxID: Must be set before the widget script loads
- HTTPS: Widget requires HTTPS in production
- CSP: Add widget domain to Content Security Policy if used
- Testing: Always test on your actual domain, not localhost
💡 Pro Tips
- Start with basic integration, then add advanced features gradually
- Use browser dev tools to debug configuration issues
- Monitor widget events to understand user behavior
- Test thoroughly across different devices and browsers
- Keep fallback search functionality for users with JavaScript disabled