Security hardening + new tools deployment
- Hide Apache version (ServerTokens Prod) - Add Permissions-Policy header - Remove deprecated X-XSS-Protection - Consolidate security headers to .htaccess only (remove duplicates from PHP) - Deploy free tools: robots-analyzer, data-converter - Deploy tools announcement blog post - Update sitemap with new tools and blog post
This commit is contained in:
226
assets/css/cro-enhancements.css
Normal file
226
assets/css/cro-enhancements.css
Normal file
@@ -0,0 +1,226 @@
|
||||
/* Mid-Article CTA Box */
|
||||
.inline-cta {
|
||||
background: linear-gradient(135deg, #f0f7ff 0%, #e8f4fd 100%);
|
||||
padding: 24px 28px;
|
||||
border-left: 4px solid #0066cc;
|
||||
margin: 40px 0;
|
||||
border-radius: 0 8px 8px 0;
|
||||
box-shadow: 0 2px 8px rgba(0,102,204,0.1);
|
||||
}
|
||||
.inline-cta h4 {
|
||||
margin: 0 0 12px 0;
|
||||
color: #0066cc;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
.inline-cta p {
|
||||
margin: 0 0 16px 0;
|
||||
color: #333;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.inline-cta .cta-link {
|
||||
display: inline-block;
|
||||
background: #0066cc;
|
||||
color: #fff !important;
|
||||
padding: 12px 24px;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.inline-cta .cta-link:hover {
|
||||
background: #0052a3;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(0,102,204,0.3);
|
||||
}
|
||||
|
||||
/* Sticky CTA Bar */
|
||||
.sticky-cta-bar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: linear-gradient(90deg, #1a1a2e 0%, #16213e 100%);
|
||||
padding: 12px 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
z-index: 9999;
|
||||
box-shadow: 0 -4px 20px rgba(0,0,0,0.15);
|
||||
transform: translateY(100%);
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
.sticky-cta-bar.visible {
|
||||
transform: translateY(0);
|
||||
}
|
||||
.sticky-cta-bar p {
|
||||
margin: 0;
|
||||
color: #fff;
|
||||
font-size: 0.95em;
|
||||
}
|
||||
.sticky-cta-bar .btn {
|
||||
background: #00cc66;
|
||||
color: #fff;
|
||||
padding: 10px 24px;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.sticky-cta-bar .btn:hover {
|
||||
background: #00b359;
|
||||
}
|
||||
.sticky-cta-bar .close-bar {
|
||||
color: #888;
|
||||
cursor: pointer;
|
||||
padding: 5px;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
/* Exit Intent Popup */
|
||||
.exit-popup-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0,0,0,0.7);
|
||||
z-index: 10000;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.exit-popup-overlay.active {
|
||||
display: flex;
|
||||
}
|
||||
.exit-popup {
|
||||
background: #fff;
|
||||
padding: 40px;
|
||||
border-radius: 12px;
|
||||
max-width: 500px;
|
||||
width: 90%;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
animation: popIn 0.3s ease;
|
||||
}
|
||||
@keyframes popIn {
|
||||
from { transform: scale(0.8); opacity: 0; }
|
||||
to { transform: scale(1); opacity: 1; }
|
||||
}
|
||||
.exit-popup .close-popup {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
right: 20px;
|
||||
font-size: 1.5em;
|
||||
cursor: pointer;
|
||||
color: #999;
|
||||
}
|
||||
.exit-popup h3 {
|
||||
margin: 0 0 15px 0;
|
||||
color: #1a1a2e;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
.exit-popup p {
|
||||
color: #666;
|
||||
margin-bottom: 25px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.exit-popup .lead-magnet {
|
||||
background: #f8f9fa;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.exit-popup .lead-magnet img {
|
||||
width: 60px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.exit-popup input[type="email"] {
|
||||
width: 100%;
|
||||
padding: 14px;
|
||||
border: 2px solid #e0e0e0;
|
||||
border-radius: 6px;
|
||||
font-size: 1em;
|
||||
margin-bottom: 15px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.exit-popup input[type="email"]:focus {
|
||||
border-color: #0066cc;
|
||||
outline: none;
|
||||
}
|
||||
.exit-popup .btn-primary {
|
||||
width: 100%;
|
||||
background: #0066cc;
|
||||
color: #fff;
|
||||
padding: 14px;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 1em;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
}
|
||||
.exit-popup .btn-primary:hover {
|
||||
background: #0052a3;
|
||||
}
|
||||
.exit-popup .no-thanks {
|
||||
display: block;
|
||||
margin-top: 15px;
|
||||
color: #999;
|
||||
font-size: 0.9em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Case Study Callout */
|
||||
.case-study-inline {
|
||||
background: #fff;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin: 30px 0;
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
align-items: center;
|
||||
}
|
||||
.case-study-inline .metric {
|
||||
background: #00cc66;
|
||||
color: #fff;
|
||||
padding: 15px 20px;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
min-width: 80px;
|
||||
}
|
||||
.case-study-inline .metric .number {
|
||||
font-size: 1.8em;
|
||||
font-weight: 700;
|
||||
display: block;
|
||||
}
|
||||
.case-study-inline .metric .label {
|
||||
font-size: 0.75em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.case-study-inline .content {
|
||||
flex: 1;
|
||||
}
|
||||
.case-study-inline .content p {
|
||||
margin: 0 0 10px 0;
|
||||
color: #333;
|
||||
}
|
||||
.case-study-inline .content a {
|
||||
color: #0066cc;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.sticky-cta-bar {
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
padding: 15px;
|
||||
}
|
||||
.case-study-inline {
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
}
|
||||
.exit-popup {
|
||||
padding: 25px;
|
||||
}
|
||||
}
|
||||
158
assets/js/cro-enhancements.js
Normal file
158
assets/js/cro-enhancements.js
Normal file
@@ -0,0 +1,158 @@
|
||||
// CRO Enhancements - Sticky Bar, Exit Intent, Tracking
|
||||
|
||||
(function() {
|
||||
// Only run on blog articles
|
||||
if (!window.location.pathname.includes("/blog/articles/")) return;
|
||||
|
||||
// Check if user already converted or dismissed
|
||||
var hasConverted = localStorage.getItem("ukds_converted");
|
||||
var hasDismissed = localStorage.getItem("ukds_dismissed");
|
||||
var dismissedAt = localStorage.getItem("ukds_dismissed_at");
|
||||
|
||||
// Reset dismissal after 7 days
|
||||
if (dismissedAt && Date.now() - parseInt(dismissedAt) > 7 * 24 * 60 * 60 * 1000) {
|
||||
localStorage.removeItem("ukds_dismissed");
|
||||
localStorage.removeItem("ukds_dismissed_at");
|
||||
hasDismissed = null;
|
||||
}
|
||||
|
||||
// === STICKY CTA BAR ===
|
||||
var stickyBar = document.createElement("div");
|
||||
stickyBar.className = "sticky-cta-bar";
|
||||
stickyBar.innerHTML = '<p>Need expert help with your data project?</p>' +
|
||||
'<a href="/quote" class="btn" onclick="trackCTA(\'sticky_bar\')">Get Free Consultation</a>' +
|
||||
'<span class="close-bar" onclick="closeStickyBar()">×</span>';
|
||||
document.body.appendChild(stickyBar);
|
||||
|
||||
// Show sticky bar after scrolling 40%
|
||||
var stickyShown = false;
|
||||
window.addEventListener("scroll", function() {
|
||||
var scrollPercent = (window.scrollY / (document.body.scrollHeight - window.innerHeight)) * 100;
|
||||
if (scrollPercent > 40 && !stickyShown && !hasDismissed) {
|
||||
stickyBar.classList.add("visible");
|
||||
stickyShown = true;
|
||||
}
|
||||
});
|
||||
|
||||
window.closeStickyBar = function() {
|
||||
stickyBar.classList.remove("visible");
|
||||
localStorage.setItem("ukds_dismissed", "sticky");
|
||||
localStorage.setItem("ukds_dismissed_at", Date.now().toString());
|
||||
};
|
||||
|
||||
// === EXIT INTENT POPUP ===
|
||||
if (!hasConverted && !hasDismissed) {
|
||||
var popup = document.createElement("div");
|
||||
popup.className = "exit-popup-overlay";
|
||||
popup.innerHTML = '<div class="exit-popup">' +
|
||||
'<span class="close-popup" onclick="closeExitPopup()">×</span>' +
|
||||
'<h3>Wait! Before you go...</h3>' +
|
||||
'<div class="lead-magnet">' +
|
||||
'<div style="font-size:2.5em;margin-bottom:10px;">📊</div>' +
|
||||
'<strong>Free Data Project Checklist</strong>' +
|
||||
'<p style="font-size:0.9em;margin:10px 0 0 0;color:#666;">' +
|
||||
'The same checklist we use for enterprise projects</p>' +
|
||||
'</div>' +
|
||||
'<form id="exit-form" onsubmit="submitExitForm(event)">' +
|
||||
'<input type="email" name="email" placeholder="Enter your email" required>' +
|
||||
'<button type="submit" class="btn-primary">Send Me The Checklist</button>' +
|
||||
'</form>' +
|
||||
'<span class="no-thanks" onclick="closeExitPopup()">No thanks, I will figure it out myself</span>' +
|
||||
'</div>';
|
||||
document.body.appendChild(popup);
|
||||
|
||||
var exitShown = false;
|
||||
document.addEventListener("mouseout", function(e) {
|
||||
if (e.clientY < 10 && !exitShown && !hasConverted && !hasDismissed) {
|
||||
popup.classList.add("active");
|
||||
exitShown = true;
|
||||
trackCTA("exit_popup_shown");
|
||||
}
|
||||
});
|
||||
|
||||
window.closeExitPopup = function() {
|
||||
popup.classList.remove("active");
|
||||
localStorage.setItem("ukds_dismissed", "popup");
|
||||
localStorage.setItem("ukds_dismissed_at", Date.now().toString());
|
||||
};
|
||||
|
||||
window.submitExitForm = function(e) {
|
||||
e.preventDefault();
|
||||
var email = e.target.email.value;
|
||||
trackCTA("exit_popup_converted", email);
|
||||
localStorage.setItem("ukds_converted", "true");
|
||||
|
||||
popup.querySelector(".exit-popup").innerHTML =
|
||||
'<h3>🎉 Check your inbox!</h3>' +
|
||||
'<p>We sent the checklist to <strong>' + email + '</strong></p>' +
|
||||
'<p style="margin-top:20px;">' +
|
||||
'<a href="/quote" class="btn-primary" style="display:inline-block;padding:14px 28px;text-decoration:none;border-radius:6px;">Or talk to us now →</a>' +
|
||||
'</p>';
|
||||
|
||||
// Send to endpoint
|
||||
fetch("/api/lead-capture.php", {
|
||||
method: "POST",
|
||||
headers: {"Content-Type": "application/json"},
|
||||
body: JSON.stringify({
|
||||
email: email,
|
||||
source: "exit_popup",
|
||||
page: window.location.pathname
|
||||
})
|
||||
}).catch(function(err) { console.error(err); });
|
||||
};
|
||||
}
|
||||
|
||||
// === CTA TRACKING ===
|
||||
window.trackCTA = function(action, label) {
|
||||
if (typeof gtag !== "undefined") {
|
||||
gtag("event", action, {
|
||||
event_category: "CRO",
|
||||
event_label: label || window.location.pathname
|
||||
});
|
||||
}
|
||||
console.log("CTA tracked:", action, label);
|
||||
};
|
||||
|
||||
// Track all quote links
|
||||
document.querySelectorAll('a[href*="/quote"]').forEach(function(link) {
|
||||
link.addEventListener("click", function() {
|
||||
var isInlineCta = this.closest(".inline-cta") ? "inline_cta" : "other";
|
||||
trackCTA("quote_click", isInlineCta);
|
||||
});
|
||||
});
|
||||
})();
|
||||
// Social Proof Notification
|
||||
(function() {
|
||||
if (localStorage.getItem("ukds_social_proof_dismissed")) return;
|
||||
|
||||
var messages = [
|
||||
"3 businesses requested quotes today",
|
||||
"A London fintech just enquired about data scraping",
|
||||
"New project started: competitor price monitoring",
|
||||
"5 quotes sent this week"
|
||||
];
|
||||
|
||||
var notification = document.createElement("div");
|
||||
notification.id = "social-proof";
|
||||
notification.style.cssText = "position:fixed;bottom:80px;left:20px;background:#fff;padding:15px 20px;border-radius:8px;box-shadow:0 4px 20px rgba(0,0,0,0.15);z-index:9998;display:none;max-width:280px;font-size:14px;border-left:4px solid #00cc66;";
|
||||
notification.innerHTML = '<div style="display:flex;align-items:center;gap:10px;"><span style="font-size:1.5em;">🔔</span><span id="social-proof-text"></span></div><span onclick="closeSocialProof()" style="position:absolute;top:5px;right:10px;cursor:pointer;color:#999;font-size:1.2em;">×</span>';
|
||||
document.body.appendChild(notification);
|
||||
|
||||
window.closeSocialProof = function() {
|
||||
notification.style.display = "none";
|
||||
localStorage.setItem("ukds_social_proof_dismissed", Date.now());
|
||||
};
|
||||
|
||||
function showNotification() {
|
||||
var msg = messages[Math.floor(Math.random() * messages.length)];
|
||||
document.getElementById("social-proof-text").textContent = msg;
|
||||
notification.style.display = "block";
|
||||
setTimeout(function() {
|
||||
notification.style.display = "none";
|
||||
}, 6000);
|
||||
}
|
||||
|
||||
// Show after 20 seconds, then every 45 seconds
|
||||
setTimeout(showNotification, 20000);
|
||||
setInterval(showNotification, 45000);
|
||||
})();
|
||||
Reference in New Issue
Block a user