Analytics Architecture on Weebly
Weebly uses a drag-and-drop editor with a structured template system. Analytics code can be injected at three levels: site-wide through Settings, per-page through page settings, and inline through Embed Code elements. Weebly renders pages server-side and delivers static HTML with client-side JavaScript, so tracking scripts load in a standard synchronous/asynchronous pattern without SPA routing complications.
The platform operates on a section-based layout engine. Each page consists of ordered sections containing elements (text, image, embed, etc.). Custom code access depends on plan tier -- free plans restrict Header/Footer Code injection while paid plans unlock full code access.
Since Square acquired Weebly, new sites are created through Square Online. The legacy Weebly editor remains available for existing sites, but Square Online uses a different code injection system. This guide covers the classic Weebly editor.
Installing Tracking Scripts
Site-Wide Injection via Settings
The primary method for analytics deployment. Navigate to Settings > SEO > Header Code and Footer Code.
Header Code (loads in <head> on every page):
<!-- Google Tag Manager - Head -->
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXX');</script>
Footer Code (loads before </body> on every page):
<!-- Google Tag Manager - Body -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
Footer Code is the preferred location for non-critical analytics scripts to avoid render blocking:
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXX');
</script>
Per-Element Injection via Embed Code
For tracking specific page sections, drag an Embed Code element onto the page:
<script>
// Track visibility of this section
var observer = new IntersectionObserver(function(entries) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
dataLayer.push({
event: 'section_view',
section_name: 'pricing_table'
});
observer.disconnect();
}
});
}, { threshold: 0.5 });
observer.observe(document.currentScript.parentElement);
</script>
Embed Code elements render inside a <div> wrapper. The script executes in document order, so it has access to preceding DOM elements but not following ones.
Weebly App Center Integrations
Some analytics platforms offer Weebly App Center integrations that auto-inject tracking code. These install via Apps > App Center and typically insert scripts through the Weebly API:
// How Weebly apps inject code (internal API pattern)
weebly.editor.insertCode({
location: 'header', // or 'footer'
code: '<script src="https://analytics.example.com/track.js"></script>'
});
Data Layer Implementation
Weebly does not provide a native data layer. Build one manually in the Header Code:
<script>
window.dataLayer = window.dataLayer || [];
dataLayer.push({
page_type: document.body.className.indexOf('wsite-page-index') > -1 ? 'home' : 'content',
site_title: document.title,
weebly_member: typeof window.memberData !== 'undefined'
});
</script>
E-Commerce Data Layer (Weebly Store)
Weebly's built-in store exposes product data through DOM elements. Extract purchase data on the order confirmation page:
<script>
// On the Weebly store confirmation page
document.addEventListener('DOMContentLoaded', function() {
var orderDetails = document.querySelector('.wsite-com-checkout-success');
if (orderDetails) {
var total = document.querySelector('.wsite-com-order-total .wsite-com-column-2');
dataLayer.push({
event: 'purchase',
ecommerce: {
transaction_id: 'weebly_' + Date.now(),
value: total ? parseFloat(total.textContent.replace(/[^0-9.]/g, '')) : 0,
currency: 'USD'
}
});
}
});
</script>
Product View Tracking
<script>
document.addEventListener('DOMContentLoaded', function() {
var productTitle = document.querySelector('.wsite-com-product-title');
var productPrice = document.querySelector('.wsite-com-product-price');
if (productTitle) {
dataLayer.push({
event: 'view_item',
ecommerce: {
items: [{
item_name: productTitle.textContent.trim(),
price: productPrice ? parseFloat(productPrice.textContent.replace(/[^0-9.]/g, '')) : 0
}]
}
});
}
});
</script>
Common Issues
Scripts Not Firing on Published Site
Weebly's editor preview does not execute custom code from Settings. Scripts only run on the published site. Always test on the live domain, not the editor preview.
Drag-and-Drop Limitations with Code Placement
Embed Code elements cannot be placed inside certain containers (navigation, footer widgets, slide shows). If a script needs to run in a restricted area, use site-wide Header/Footer Code with DOM selectors instead:
// Target a specific section from Header Code instead of embedding inline
document.addEventListener('DOMContentLoaded', function() {
var target = document.querySelector('#wsite-content .wsite-section-wrap:nth-child(3)');
if (target) {
// Attach tracking to this section
}
});
Weebly's Built-In Analytics Conflict
Weebly includes its own analytics (weeblytracker.js) which fires page views automatically. If you also run Google Analytics, you may see inflated page view counts. Weebly's tracker runs on a separate system and does not interact with dataLayer or GA, but verify your reporting excludes internal Weebly analytics hits.
Square Online Migration Breaks Code Injection
Sites migrated from Weebly to Square Online lose Header/Footer Code settings. Square Online uses a different injection point: Website > Settings > Tracking Tools > Additional Scripts. After migration, revalidate all analytics tags.
Embed Code Elements Stripped on Plan Downgrade
Downgrading from a paid plan to free removes access to Embed Code elements and Header/Footer Code. The code remains in the site data but stops rendering. Verify tag firing after any plan change.
Platform-Specific Considerations
DOM Structure: Weebly wraps pages in #wsite-content with sections in .wsite-section-wrap elements. Product pages use .wsite-com-product-* classes. These selectors are stable across templates.
Mobile Rendering: Weebly serves the same HTML to mobile and desktop, using CSS media queries. Mobile-specific tracking should use viewport detection, not user-agent sniffing.
Weebly Members Area: Sites with membership features expose window.memberData when a user is logged in. Use this for authenticated user tracking:
if (typeof window.memberData !== 'undefined') {
dataLayer.push({
user_status: 'member',
member_id: window.memberData.id
});
}
Form Submission Tracking: Weebly forms submit via AJAX. Listen for the success response:
document.addEventListener('submit', function(e) {
if (e.target.classList.contains('wsite-form')) {
dataLayer.push({
event: 'form_submit',
form_name: e.target.closest('.wsite-section-wrap') ?
'section_' + Array.from(document.querySelectorAll('.wsite-section-wrap'))
.indexOf(e.target.closest('.wsite-section-wrap')) : 'unknown'
});
}
});
Caching: Weebly uses aggressive CDN caching. After updating tracking code in Settings, allow up to 15 minutes for changes to propagate. Force-refresh (Ctrl+Shift+R) when testing.