🎬 Intersection Observer for Viewport Tracking
Generates backlinks only when content enters viewport (optimal performance).
html
<script>
(function() {
'use strict';
const CONFIG = {
contentSelector: '.post-content, article, main',
threshold: 0.3, // 30% visible
rootMargin: '50px',
generateOnce: true
};
const processedElements = new Set();
// Backlink builder
function buildBacklink() {
const metadata = {
title: document.title || 'Page',
description: document.querySelector('meta[name="description"]')?.content ||
document.querySelector('p')?.textContent?.substring(0, 160) ||
'Content',
url: window.location.href
};
const params = new URLSearchParams(metadata);
return `https://aepiot.com/backlink.html?${params.toString()}`;
}
// Create backlink widget
function createWidget(url) {
const widget = document.createElement('aside');
widget.className = 'aepiot-viewport-widget';
widget.setAttribute('role', 'complementary');
widget.setAttribute('aria-label', 'Page backlink');
Object.assign(widget.style, {
position: 'sticky',
top: '20px',
margin: '30px 0',
padding: '20px',
background: 'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
borderRadius: '16px',
boxShadow: '0 8px 32px rgba(245, 87, 108, 0.3)',
textAlign: 'center',
animation: 'slideInRight 0.6s ease-out'
});
widget.innerHTML = ` <style>
@keyframes slideInRight {
from {
opacity: 0;
transform: translateX(50px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
.aepiot-widget-link {
transition: all 0.3s ease;
}
.aepiot-widget-link:hover {
transform: scale(1.05);
}
</style>
<div style="color: white;">
<div style="font-size: 28px; margin-bottom: 8px;">✨</div>
<div style="font-weight: 700; font-size: 18px; margin-bottom: 8px;">
Share This Content
</div>
<div style="font-size: 14px; opacity: 0.95; margin-bottom: 16px;">
Get your aéPiot backlink now
</div>
<a href="${url}"
class="aepiot-widget-link"
target="_blank"
rel="noopener noreferrer"
style="display: inline-block; padding: 12px 28px; background: white;
color: #f5576c; text-decoration: none; border-radius: 10px;
font-weight: 700; font-size: 15px;">
Get Backlink
</a>
</div>
`;
return widget;
}
// Intersection callback
function handleIntersection(entries, observer) {
entries.forEach(entry => {
if (entry.isIntersecting && !processedElements.has(entry.target)) {
// Mark as processed
if (CONFIG.generateOnce) {
processedElements.add(entry.target);
observer.unobserve(entry.target);
}
// Generate backlink
const url = buildBacklink();
const widget = createWidget(url);
// Insert at the end of content
entry.target.appendChild(widget);
console.log('[aéPiot] Viewport-triggered backlink generated');
// Analytics
if (typeof gtag !== 'undefined') {
gtag('event', 'aepiot_viewport_generated', {
'event_category': 'engagement',
'viewport_percent': Math.round(entry.intersectionRatio * 100)
});
}
}
});
}
// Initialize
function initialize() {
const targets = document.querySelectorAll(CONFIG.contentSelector);
if (targets.length === 0) {
console.warn('[aéPiot] No content elements found');
return;
}
const observerOptions = {
threshold: CONFIG.threshold,
rootMargin: CONFIG.rootMargin
};
const observer = new IntersectionObserver(handleIntersection, observerOptions);
targets.forEach(target => {
observer.observe(target);
});
console.log(`[aéPiot] Observing ${targets.length} content elements`);
}
// Start
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initialize);
} else {
initialize();
}
})();
</script>Features:
- 👁️ Viewport-based generation
- ⚡ Excellent performance (no scroll events)
- 🎨 Animated entrance
- 📌 Sticky positioning
- 🎯 Configurable thresholds
- 📊 Analytics integration
Continue to Part 4: Production & Optimization →
Alternative aéPiot Working Scripts Guide - Part 4: Production & Optimization
Performance, Monitoring, and Deployment Best Practices
🚀 Performance-Optimized Async Script
Loads and executes without blocking page rendering.
html
<script>
(async function() {
'use strict';
// Configuration
const CONFIG = {
apiEndpoint: 'https://aepiot.com/backlink.html',
cacheKey: 'aepiot_backlink_cache',
cacheDuration: 3600000, // 1 hour in milliseconds
retryAttempts: 3,
retryDelay: 1000
};
// Performance monitoring
const Performance = {
marks: {},
start(label) {
this.marks[label] = performance.now();
},
end(label) {
if (this.marks[label]) {
const duration = performance.now() - this.marks[label];
console.log(`[aéPiot Performance] ${label}: ${duration.toFixed(2)}ms`);
delete this.marks[label];
return duration;
}
},
measure(label, fn) {
this.start(label);
const result = fn();
this.end(label);
return result;
}
};
// Cache manager
const Cache = {
get(key) {
try {
const item = localStorage.getItem(key);
if (!item) return null;
const data = JSON.parse(item);
// Check expiration
if (Date.now() > data.expiry) {
this.remove(key);
return null;
}
return data.value;
} catch (error) {
console.error('[aéPiot Cache] Read error:', error);
return null;
}
},
set(key, value, duration = CONFIG.cacheDuration) {
try {
const data = {
value: value,
expiry: Date.now() + duration
};
localStorage.setItem(key, JSON.stringify(data));
} catch (error) {
console.error('[aéPiot Cache] Write error:', error);
}
},
remove(key) {
try {
localStorage.removeItem(key);
} catch (error) {
console.error('[aéPiot Cache] Remove error:', error);
}
}
};
// Metadata extractor with caching
const MetadataExtractor = {
async extract() {
Performance.start('metadata_extraction');
// Try cache first
const cacheKey = `${CONFIG.cacheKey}_${window.location.pathname}`;
const cached = Cache.get(cacheKey);
if (cached) {
Performance.end('metadata_extraction');
console.log('[aéPiot] Using cached metadata');
return cached;
}
// Extract fresh metadata
const metadata = {
title: await this.extractTitle(),
description: await this.extractDescription(),
url: this.extractURL(),
timestamp: Date.now()
};
// Cache for future use
Cache.set(cacheKey, metadata);
Performance.end('metadata_extraction');
return metadata;
},
async extractTitle() {
// Check various sources in priority order
const sources = [
() => document.querySelector('meta[property="og:title"]')?.content,
() => document.querySelector('meta[name="twitter:title"]')?.content,
() => document.title,
() => document.querySelector('h1')?.textContent?.trim(),
() => 'Untitled Page'
];
for (const source of sources) {
const title = source();
if (title && title.length > 5) {
return title;
}
}
return 'Untitled Page';
},
async extractDescription() {
// Check various sources
const sources = [
() => document.querySelector('meta[name="description"]')?.content,
() => document.querySelector('meta[property="og:description"]')?.content,
() => document.querySelector('meta[name="twitter:description"]')?.content,
() => this.getFirstParagraph(),
() => 'Quality content available on this page'
];
for (const source of sources) {
const description = source();
if (description && description.length > 20) {
return description.substring(0, 160);
}
}
return 'Quality content available on this page';
},
getFirstParagraph() {
const selectors = [
'article p',
'main p',
'.entry-content p',
'.post-content p',
'.content p',
'p'
];
for (const selector of selectors) {
const element = document.querySelector(selector);
if (element) {
const text = element.textContent.trim();
if (text.length > 50) {
return text;
}
}
}
return null;
},
extractURL() {
return document.querySelector('link[rel="canonical"]')?.href ||
document.querySelector('meta[property="og:url"]')?.content ||
window.location.href;
}
};
// URL generator with retry logic
const URLGenerator = {
async generate(metadata, attempt = 1) {
try {
Performance.start('url_generation');
// Sanitize and validate
const sanitized = {
title: this.sanitize(metadata.title, 200),
description: this.sanitize(metadata.description, 500),
url: metadata.url
};
// Validate URL
if (!this.isValidURL(sanitized.url)) {
throw new Error('Invalid URL');
}
// Build backlink URL
const params = new URLSearchParams({
title: sanitized.title,
description: sanitized.description,
link: sanitized.url
});
const backlinkURL = `${CONFIG.apiEndpoint}?${params.toString()}`;
Performance.end('url_generation');
return { success: true, url: backlinkURL };
} catch (error) {
console.error(`[aéPiot] Generation attempt ${attempt} failed:`, error);
// Retry logic
if (attempt < CONFIG.retryAttempts) {
await this.sleep(CONFIG.retryDelay * attempt);
return this.generate(metadata, attempt + 1);
}
return { success: false, error: error.message };
}
},
sanitize(text, maxLength) {
if (!text) return '';
// Remove control characters and excess whitespace
text = text.replace(/[\x00-\x1F\x7F]/g, '')
.replace(/\s+/g, ' ')
.trim();
// Truncate if needed
if (text.length > maxLength) {
text = text.substring(0, maxLength - 3) + '...';
}
return text;
},
isValidURL(url) {
try {
const parsed = new URL(url);
return parsed.protocol === 'http:' || parsed.protocol === 'https:';
} catch {
return false;
}
},
sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
};
// UI renderer with progressive enhancement
const UIRenderer = {
async render(backlinkURL) {
Performance.start('ui_render');
const container = this.createContainer();
const content = await this.createContent(backlinkURL);
container.appendChild(content);
this.insert(container);
Performance.end('ui_render');
// Animate in
requestAnimationFrame(() => {
container.style.opacity = '1';
container.style.transform = 'translateY(0)';
});
},
createContainer() {
const container = document.createElement('div');
container.className = 'aepiot-optimized-container';
container.setAttribute('role', 'complementary');
Object.assign(container.style, {
margin: '30px 0',
opacity: '0',
transform: 'translateY(20px)',
transition: 'opacity 0.4s ease, transform 0.4s ease',
willChange: 'opacity, transform'
});
return container;
},
async createContent(url) {
const content = document.createElement('div');
Object.assign(content.style, {
padding: '24px',
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
borderRadius: '12px',
boxShadow: '0 10px 40px rgba(0,0,0,0.1)',
textAlign: 'center'
});
content.innerHTML = ` <div style="color: white;">
<div style="font-size: 32px; margin-bottom: 12px;">🔗</div>
<div style="font-weight: 700; font-size: 20px; margin-bottom: 8px;">
aéPiot Backlink Ready
</div>
<div style="font-size: 14px; opacity: 0.95; margin-bottom: 20px;">
Share this page with a semantic backlink
</div>
<div style="display: flex; gap: 12px; justify-content: center; flex-wrap: wrap;">
<a href="${url}"
target="_blank"
rel="noopener noreferrer"
style="padding: 12px 28px; background: white; color: #667eea;
text-decoration: none; border-radius: 8px; font-weight: 700;
transition: transform 0.2s ease; display: inline-block;"
onmouseenter="this.style.transform='scale(1.05)'"
onmouseleave="this.style.transform='scale(1)'">
Open Link
</a>
<button onclick="navigator.clipboard.writeText('${url.replace(/'/g, "\\'")}'); this.textContent='✅ Copied!'; setTimeout(() => this.textContent='📋 Copy', 2000)"
style="padding: 12px 28px; background: rgba(255,255,255,0.2);
color: white; border: 2px solid white; border-radius: 8px;
font-weight: 700; cursor: pointer; transition: all 0.2s ease;"
onmouseenter="this.style.background='rgba(255,255,255,0.3)'"
onmouseleave="this.style.background='rgba(255,255,255,0.2)'">
📋 Copy
</button>
</div>
</div>
`;
return content;
},
insert(container) {
const insertionPoint = document.querySelector('article, main, .content') || document.body;
// Try to insert at a natural break
const lastHeading = insertionPoint.querySelector('h2:last-of-type, h3:last-of-type');
if (lastHeading) {
lastHeading.insertAdjacentElement('afterend', container);
} else {
insertionPoint.appendChild(container);
}
}
};
// Error handler
const ErrorHandler = {
handle(error, context) {
console.error(`[aéPiot Error] ${context}:`, error);
// Log to external service if available
if (typeof Sentry !== 'undefined') {
Sentry.captureException(error, {
tags: { context, component: 'aepiot' }
});
}
// Show user-friendly message
this.showErrorUI(error);
},
showErrorUI(error) {
const container = document.createElement('div');
Object.assign(container.style, {
margin: '20px 0',
padding: '16px',
background: '#fef2f2',
border: '1px solid #fecaca',
borderRadius: '8px',
color: '#991b1b',
fontSize: '14px'
});
container.innerHTML = ` <strong>⚠️ Unable to generate backlink</strong>
<p style="margin: 8px 0 0 0; color: #7f1d1d;">
Please try refreshing the page or contact support if the issue persists.
</p>
`;
const insertionPoint = document.querySelector('article, main') || document.body;
insertionPoint.appendChild(container);
}
};
// Main execution
async function main() {
Performance.start('total_execution');
try {
// Extract metadata
const metadata = await MetadataExtractor.extract();
// Generate backlink URL
const result = await URLGenerator.generate(metadata);
if (result.success) {
// Render UI
await UIRenderer.render(result.url);
console.log('[aéPiot] Successfully generated backlink');
// Analytics
if (typeof gtag !== 'undefined') {
gtag('event', 'aepiot_optimized_generated', {
'event_category': 'performance',
'performance_time': Performance.end('total_execution')
});
}
} else {
throw new Error(result.error);
}
} catch (error) {
ErrorHandler.handle(error, 'main_execution');
}
}
// Defer execution until page is interactive
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', main);
} else if (document.readyState === 'interactive') {
// Wait for next idle period
if ('requestIdleCallback' in window) {
requestIdleCallback(main, { timeout: 2000 });
} else {
setTimeout(main, 1000);
}
} else {
// Page already loaded
main();
}
})();
</script>Features:
- ⚡ Async/await for non-blocking execution
- 💾 localStorage caching
- 🔄 Automatic retry logic
- 📊 Performance monitoring
- 🎯 Progressive enhancement
- ❌ Comprehensive error handling
- 📈 Analytics integration
- 🚀 RequestIdleCallback optimization