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.