Debugging Webflow Custom JavaScript: A Triage Checklist for Slater Users

If your Webflow custom JavaScript isn’t working, run this checklist in order—most issues are connection, environment, scoping, or dependency order problems.

Head-start triage (5 quick checks)

  • Connection present: Confirm your site includes the one-time Slater snippet in Webflow → Project settings → Custom code. In DevTools → Console, you should see "Slater loaded [Project Name] (Slater.app/1234)".
  • Correct environment: Verify you published the correct file to Staging vs Production and you’re testing on the matching domain (webflow.io vs custom domain).
  • No duplicates: Ensure migrated code isn’t still in Webflow embeds. Double execution is a common culprit.
  • Console first: Open DevTools → Console for syntax errors and undefined references; fix the first error before proceeding.
  • Dependencies first: If you rely on a library (e.g., GSAP), confirm it loads before your code (DevTools → Network, then check window.GSAP or relevant global).

Scope code to the elements you enhance (avoid running everywhere)

  • Guard for presence so your script only runs where it should and won’t error on pages that don’t have the feature.
const root = document.querySelector('[data-module="gallery"]');if (!root) {// This page doesn’t have the gallery; exit safely.} else {if (root.dataset.inited) return; // prevent double‑init  root.dataset.inited = '1';initGallery(root);}function initGallery(el) {// Your feature logic}

Prevent double initialization

  • Mark elements you’ve initialized. If your code can be re-evaluated (e.g., due to page transitions or re-renders), use a data flag as shown above to keep behavior stable.

Verify environment and publishing flow

  • Staging first: Publish changes to Staging in Slater and validate them on your webflow.io domain.
  • Promote intentionally: Only publish to Production after your staging checks pass.
  • Smart loading: If you use Slater’s Smart Script, it can load the right file per domain automatically.

Resolve ordering and third‑party libraries

  • Wait for a global safely without load events:
function waitForGlobal(key, cb) {if (window[key]) return cb(window[key]);const id = setInterval(() => {if (window[key]) { clearInterval(id); cb(window[key]); }  }, 50);}waitForGlobal('gsap', (gsap) => {// Safe to use gsap here});

Handle Webflow Interactions and selectors cleanly

  • Avoid overly brittle selectors that may change in the Designer. Prefer data attributes for targets (e.g., [data-module], [data-action]).
  • If an interaction also manipulates the same element, namespace your classes and limit mutation overlap.

Caching and “it works on staging but not live”

  • Hard refresh or append a version query to your hosted file reference on first load after deploy (e.g., ?v=2025-12-31) if needed.
  • Confirm production actually loaded the newest Slater file (DevTools → Network → Disable cache, refresh).

Minimal decision tree

  • Error in console? Fix the first error; it often cascades.
  • No file in Network? Re-add the Slater snippet at site level and re-publish the site.
  • Wrong environment? Check which domain you’re on and what you last published in Slater.
  • Feature on wrong pages? Add presence guards and page scoping.
  • Using libraries? Verify they load before your code and only once.

FAQ

  • Do I need to publish Webflow after every change? No. Once the Slater snippet is in place, most iterations happen in Slater. Re-publish Webflow only when you change the snippet or site settings.
  • Can I mix Slater with some page-level embeds? Yes—just avoid duplicating the same logic in two places.
  • It works locally but not in Webflow—why? Check selectors, library load order, and whether the element exists when your code executes. Scope by element presence as shown above.
Jared Malan