Widget Troubleshooting
Fix common issues with the Refgrow affiliate widget, including disappearing widgets and visibility problems.
Common Problem: Widget Disappears on Tab Switch
Some users report that the Refgrow widget disappears or becomes empty when:
- Switching between browser tabs
- Returning to the page after being away
- Navigating in Single Page Applications (SPAs)
- Losing window focus
Automatic Recovery Solution
Use our widget script that includes automatic recovery functionality:
html
<div id="refgrow" data-project-id="YOUR_PROJECT_ID"></div>
<script src="https://scripts.refgrowcdn.com/page.js"></script>Automatic Features:
- Automatic recovery when switching browser tabs
- Periodic health checks every 10 seconds
- Page visibility change detection
- Window focus/blur event handling
- Manual recovery methods for custom implementations
Manual Recovery Methods
If you need to manually restore the widget or implement custom recovery logic:
JavaScript
javascript
// Check and restore the widget
window.Refgrow.restore();
// Force re-initialization
window.Refgrow.forceInit();
// Complete reset and re-initialization
window.Refgrow.reset();
window.Refgrow.init();TypeScript
typescript
// TypeScript interface for Refgrow methods
interface RefgrowWidget {
restore(): void;
forceInit(): void;
reset(): void;
init(): void;
}
// Usage
declare global {
interface Window {
Refgrow: RefgrowWidget;
}
}
// Check and restore the widget
window.Refgrow.restore();
// Force re-initialization
window.Refgrow.forceInit();SPA Framework Integration
For Single Page Applications, you may need additional integration to handle route changes and component lifecycles:
React
javascript
import { useEffect } from 'react';
function RefgrowWidget({ projectId, userEmail }) {
useEffect(() => {
// Initialize widget when component mounts
const element = document.getElementById('refgrow');
if (element && window.Refgrow) {
window.Refgrow.forceInit();
}
}, []);
useEffect(() => {
// Check widget state on route changes
const timer = setTimeout(() => {
if (window.Refgrow) {
window.Refgrow.restore();
}
}, 500);
return () => clearTimeout(timer);
});
// Handle page visibility changes
useEffect(() => {
const handleVisibilityChange = () => {
if (!document.hidden && window.Refgrow) {
setTimeout(() => {
const element = document.getElementById('refgrow');
if (element && element.innerHTML.trim() === '') {
window.Refgrow.restore();
}
}, 1000);
}
};
document.addEventListener('visibilitychange', handleVisibilityChange);
return () => {
document.removeEventListener('visibilitychange', handleVisibilityChange);
};
}, []);
return (
<div
id="refgrow"
data-project-id={projectId}
data-project-email={userEmail}
></div>
);
}Vue.js
javascript
<template>
<div
id="refgrow"
:data-project-id="projectId"
:data-project-email="userEmail"
></div>
</template>
<script>
export default {
name: 'RefgrowWidget',
props: {
projectId: {
type: String,
required: true
},
userEmail: {
type: String,
default: null
}
},
mounted() {
this.initWidget();
this.setupVisibilityListener();
},
activated() {
// For keep-alive components
this.$nextTick(() => {
this.restoreWidget();
});
},
beforeUnmount() {
this.cleanup();
},
methods: {
initWidget() {
if (window.Refgrow) {
window.Refgrow.forceInit();
}
},
restoreWidget() {
if (window.Refgrow) {
window.Refgrow.restore();
}
},
setupVisibilityListener() {
this.handleVisibilityChange = () => {
if (!document.hidden && window.Refgrow) {
setTimeout(() => {
const element = document.getElementById('refgrow');
if (element && element.innerHTML.trim() === '') {
window.Refgrow.restore();
}
}, 1000);
}
};
document.addEventListener('visibilitychange', this.handleVisibilityChange);
},
cleanup() {
if (this.handleVisibilityChange) {
document.removeEventListener('visibilitychange', this.handleVisibilityChange);
}
if (window.Refgrow) {
window.Refgrow.reset();
}
}
}
}
</script>Angular
typescript
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
declare global {
interface Window {
Refgrow: any;
}
}
@Component({
selector: 'app-refgrow-widget',
template: `
<div
id="refgrow"
[attr.data-project-id]="projectId"
[attr.data-project-email]="userEmail"
></div>
`
})
export class RefgrowWidgetComponent implements OnInit, OnDestroy {
@Input() projectId!: string;
@Input() userEmail?: string;
private visibilityChangeHandler?: () => void;
ngOnInit() {
this.initWidget();
this.setupVisibilityListener();
}
ngOnDestroy() {
this.cleanup();
}
private initWidget() {
setTimeout(() => {
if (window.Refgrow) {
window.Refgrow.forceInit();
}
}, 100);
}
private restoreWidget() {
if (window.Refgrow) {
window.Refgrow.restore();
}
}
private setupVisibilityListener() {
this.visibilityChangeHandler = () => {
if (!document.hidden && window.Refgrow) {
setTimeout(() => {
const element = document.getElementById('refgrow');
if (element && element.innerHTML.trim() === '') {
window.Refgrow.restore();
}
}, 1000);
}
};
document.addEventListener('visibilitychange', this.visibilityChangeHandler);
}
private cleanup() {
if (this.visibilityChangeHandler) {
document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
}
if (window.Refgrow) {
window.Refgrow.reset();
}
}
}Custom Visibility Monitoring
For advanced use cases, you can implement your own visibility monitoring:
javascript
// Enhanced visibility monitoring
document.addEventListener('visibilitychange', function() {
if (!document.hidden) {
// Page became visible
setTimeout(function() {
const element = document.getElementById('refgrow');
if (element && element.innerHTML.trim() === '' && window.Refgrow) {
console.log('Restoring empty Refgrow widget');
window.Refgrow.restore();
}
}, 1000);
}
});
// Periodic health check
function healthCheck() {
const element = document.getElementById('refgrow');
const isEmpty = !element || element.innerHTML.trim() === '';
if (isEmpty && window.Refgrow) {
console.warn('Refgrow widget appears empty, attempting restore...');
window.Refgrow.restore();
}
return !isEmpty;
}
// Run health check every 30 seconds
setInterval(healthCheck, 30000);Debugging Widget Issues
Use these debugging techniques to diagnose widget problems:
javascript
// Debug widget status
function checkRefgrowStatus() {
const element = document.getElementById('refgrow');
console.log('Refgrow element:', element);
console.log('Element content:', element ? element.innerHTML : 'Not found');
console.log('Refgrow object:', window.Refgrow);
console.log('ReferralProgram object:', window.ReferralProgram);
}
// Run debug check
checkRefgrowStatus();
// Monitor for errors
window.addEventListener('error', function(e) {
if (e.message && e.message.includes('Refgrow')) {
console.error('Refgrow widget error:', e);
// Send error to your monitoring service
}
});Platform-Specific Solutions
WordPress
Add this to your theme's functions.php:
javascript
function refgrow_widget_monitor() {
?>
<script>
jQuery(document).ready(function($) {
setInterval(function() {
if (window.Refgrow && $('#refgrow').is(':empty')) {
window.Refgrow.restore();
}
}, 10000);
});
</script>
<?php
}
add_action('wp_footer', 'refgrow_widget_monitor');Shopify
Add to your theme's theme.liquid:
html
{% comment %} Refgrow Widget Monitor {% endcomment %}
<script>
document.addEventListener('DOMContentLoaded', function() {
// Monitor for theme changes
document.addEventListener('shopify:section:load', function() {
setTimeout(function() {
if (window.Refgrow) {
window.Refgrow.restore();
}
}, 1000);
});
});
</script>Performance Optimization
Important: While monitoring helps ensure widget availability, avoid excessive polling that could impact page performance.
Best Practices:
- Use the built-in recovery mechanisms first
- Implement debounced visibility checks
- Limit health check frequency to 10-30 seconds
- Use Intersection Observer for performance-sensitive applications
- Clean up event listeners when components unmount
javascript
// Debounced restore function
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
// Debounced widget restore
const debouncedRestore = debounce(() => {
if (window.Refgrow) {
window.Refgrow.restore();
}
}, 1000);
// Use Intersection Observer for better performance
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting && entry.target.innerHTML.trim() === '') {
debouncedRestore();
}
});
});
const refgrowElement = document.getElementById('refgrow');
if (refgrowElement) {
observer.observe(refgrowElement);
}Still Having Issues?
If the widget is still not working properly after trying these solutions:
- Check browser console for JavaScript errors
- Verify you are using the latest version of page.js
- Test manual restoration with
window.Refgrow.restore() - Check for conflicts with other scripts or frameworks
- Contact support with console logs and detailed reproduction steps
Need help? Contact us at support@refgrow.com with:
- Browser console logs
- Steps to reproduce the issue
- Your website URL (if possible)
- Framework/platform you are using