Source: ai-research/ghl-2026-05-01/support-solutions-articles-155000003278-unlocking-customization-enhancing-marketplace-apps-with-custom-javascript.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.
- Five safety rules govern what your script can and can’t do — see Guidelines section. Violations get rejected; repeated violations risk app delisting.
- 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 five 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 | JS must be embedded correctly within HighLevel’s expected wrapper. (Source truncates here; check the developer portal Custom JS module for the current embedding template.) |
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 five 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.
- 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
- The source is truncated at the embedding rule — the exact wrapper format / embedding template isn’t reproduced here. Check the developer portal Custom JS module for the current spec.
- 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?
- CSP behavior of the embedded script context (what APIs are blocked at runtime regardless of review approval).