Source: ai-research/ghl-2026-05-01/support-solutions-articles-155000003278-unlocking-customization-enhancing-marketplace-apps-with-custom-javascript.md, ai-research/ghl-2026-07-02-drain/support-solutions-articles-155000003278-custom-javascript-full-refetch.md
The Custom JavaScript module lets agency-distributed Marketplace apps inject custom JS and CSS into the HighLevel platform UI. It’s an escape hatch for personalization that the OAuth API alone can’t reach — DOM tweaks, custom UI elements layered on top of the standard UI, brand-specific styling. Because injected scripts run in the customer’s HighLevel session, every submission goes through a 10-business-day security review before it’s embedded in the agency app.
Key Takeaways
- Distribution gate. Only apps with distribution type Agency or Agency & Sub-account can ship Custom JavaScript. Sub-account-only apps cannot use this feature.
- Review SLA: up to 10 business days. Every script goes through HighLevel’s review team. Approved scripts are embedded in the agency app on next deploy.
- Six safety rules govern what your script can and can’t do — see Guidelines section. Violations get rejected; repeated violations risk app delisting.
- Embedding “wrapper” is just a standard
<script>tag. There’s no special HighLevel envelope format — wrap your JS in normal<script>tags and stripconsole.logcalls before submitting. - Test before you submit. The Custom JavaScript & Custom CSS section under Agency view → Settings → Company lets you paste and preview your script in a live-ish environment before it goes through the 10-day review. No agency access? Use a sandbox account instead.
- Use cases: custom UI overlays, brand-specific styling, dashboards, in-app notifications, custom integrations that the OAuth API can’t reach. Anything requiring DOM-level access.
- Don’t use this for: logic that fits the OAuth API. Stick to OAuth where you can — Custom JS is the last-resort, review-gated path.
Guidelines for Custom Scripts
Submission guidelines (all six must hold):
| Rule | Meaning |
|---|---|
| No sensitive data access | Custom scripts cannot read or manipulate sensitive customer data. The script lives in the page; it must not query for credentials, tokens, PII, or financial data. |
| No obfuscated code | Submit clear, readable code. Minified-but-readable bundles are fine; obfuscated/packed scripts (jsfuck, eval-rolled, runtime-decoded) are rejected. The review team must be able to reason about every line. |
| No direct database access | Scripts must not attempt to bypass the API and reach storage layers directly. |
| No remote file references | All logic must be self-contained. No <script src="https://your-cdn.com/...">, no dynamic import() of off-platform URLs, no on-the-fly script loading. The bundle reviewed is the bundle that runs. |
| Properly embedded scripts | Wrap your JS in standard <script> tags for correct DOM integration — that’s the entire “wrapper format”: no special HighLevel-specific envelope, just a normal inline <script> block. |
| No console.log statements | Strip debug logging before submission. The review team treats leftover console.log calls as unclean/non-production code. |
Why these rules exist
Custom JS runs inside the customer’s authenticated HighLevel session — same origin, same cookies, same browser context. A malicious or buggy script could exfiltrate data, hijack the session, or interfere with the platform. The six rules together ensure:
- The review team can statically analyze the script (no obfuscation, no remote loads)
- The script can’t escalate privileges (no DB access, no sensitive data)
- The deployed code matches the reviewed code (no remote file references)
This is why the review SLA is days, not minutes — every submission gets read by hand.
Review Process
- Build your custom JS/CSS as part of your agency app, wrapped in standard
<script>tags with noconsole.logcalls left in. - Test before submitting. Paste the script into Agency view → Settings → Company → Custom JavaScript & Custom CSS to preview behavior before review. If you don’t have agency access, simulate the environment in a sandbox account.
- Submit through the developer portal under Custom JS / CustomJS module.
- Wait up to 10 business days for review.
- On approval, scripts are embedded into the agency app on the next deploy.
- On rejection, you receive feedback indicating which rule failed; revise and resubmit.
Try It
- Audit your use case before submitting: if you can do it via OAuth API + standard scopes, do that — Custom JS is heavyweight and review-gated.
- Keep your bundle small and readable. Use a build pipeline that produces minified-but-not-obfuscated output (e.g., esbuild with
minify: true, mangleProps: false). - Inline every dependency. No external
<script>tags. If you need a small library (lodash function, date helper), copy the function in or transpile it into your bundle. - Avoid touching elements that show sensitive content (payment forms, contact PII). The review team will reject anything that looks like a credential-capture surface.
- Submit early in the cycle and treat 10 business days as the worst case for planning.
Related
Open Questions
- Whether CSS-only submissions go through the same 10-day review or have a faster track.
Versioning behavior — when an approved script is updated, does the new version need re-review, or is there an incremental-update path?Resolved 2026-07-03 — see Developer Marketplace § App Versioning. Short answer: Custom JS is a “Module,” not tied to the new app-versioning lifecycle (Draft → In Review → Live). HighLevel’s own changelog states modules “are currently associated with the app, not a specific version” and changes “may become visible immediately after saving” — no confirmed re-review gate for the script content itself, unlike a full app version bump. “Version-aware module updates” is explicitly on HighLevel’s roadmap, meaning HighLevel itself confirms this gap is real and not yet closed.- CSP behavior of the embedded script context (what APIs are blocked at runtime regardless of review approval). (researched 2026-07-02: still open — no HighLevel doc found describing a technical runtime sandbox for Custom JS beyond the human review gate. The existing “Why these rules exist” section above already establishes the script runs same-origin/same-session with no iframe isolation; no additional CSP-specific restriction list was found in official docs or changelogs.)