Jamdesk Documentation logo

Custom JavaScript

Add custom JavaScript to your docs site for chat widgets, analytics, third-party integrations, and other client-side functionality.

Custom JavaScript runs on every page of your docs site. Use it for chat widgets, analytics, or any other client-side script you need.

Adding Custom JavaScript

Create a JavaScript file in your docs directory and reference it in docs.json:

docs.json
{
  "styling": {
    "js": "/script.js"
  }
}
script.js
// Your custom JavaScript runs on every page
console.log('Hello from custom JS!');

Jamdesk inlines your script into the page HTML. It executes as the page loads.

Auto-Detection

Without styling.js, Jamdesk detects .js files in your project root directory. Drop a script.js file next to your docs.json to include it.

my-docs/
├── docs.json
├── script.js      ← auto-detected
├── introduction.mdx
└── getting-started.mdx

Configuring styling.js in docs.json turns off auto-detection. Only the listed files are used.

Auto-detection includes every .js file in your project root, including utility scripts like eslint.config.js or postcss.config.js. List exactly which files to include with styling.js in docs.json.

Multiple Files

Include multiple scripts by passing an array:

docs.json
{
  "styling": {
    "js": ["/chat.js", "/analytics.js"]
  }
}

Auto-detection includes every .js file in the root, sorted alphabetically. analytics.js loads before chat.js.

Examples

CSS & JS Examples pairs a script with CSS. It adds a floating Ask AI button and a brand-colored header.

Chat Widget (Crisp)

script.js
window.$crisp = [];
window.CRISP_WEBSITE_ID = "your-website-id";
(function () {
  var d = document;
  var s = d.createElement("script");
  s.src = "https://client.crisp.chat/l.js";
  s.async = 1;
  d.getElementsByTagName("head")[0].appendChild(s);
})();

Custom Analytics

script.js
// Track outbound link clicks
document.addEventListener('click', function (e) {
  var link = e.target.closest('a[href^="http"]');
  if (link && !link.href.includes(window.location.hostname)) {
    console.log('Outbound click:', link.href);
    // Send to your analytics service
  }
});

Feedback Widget

script.js
// Load a feedback widget after the page is ready
window.addEventListener('load', function () {
  var s = document.createElement('script');
  s.src = 'https://your-feedback-tool.com/widget.js';
  s.setAttribute('data-project', 'your-project-id');
  document.body.appendChild(s);
});

How It Works

The build reads your JavaScript files and embeds them in the HTML of every page. The script tag sits at the end of <body>. The DOM is available when your code runs.

Custom JavaScript also runs in jamdesk dev (CLI 1.1.222 and later). Test a script there before you push. Errors thrown by your script appear in the browser console. window.__JAMDESK_DEV__ is true in jamdesk dev. Use it to skip production-only code such as analytics:

if (!window.__JAMDESK_DEV__) {
  // analytics, chat widgets and other production-only code
}

If you configure cookie consent with integrations.cookies, your script runs only on the published site, after the visitor gives consent.

The script runs once, when a visitor first loads your site. Clicking a link inside the docs swaps the page content without a full reload. The script doesn't run again. Code that reads or changes the page content should watch for page changes.

Limitations

  • Scripts run on every page. There's no way to target specific pages
  • Changes take effect on your next build
  • Scripts are inlined into the HTML, not served as separate files
  • Prefer the built-in integrations for analytics. They take care of consent and performance for you

What's Next?

Custom CSS

Override theme styles with custom CSS

CSS & JS Examples

A floating Ask AI button and a branded header

Integrations

Built-in analytics and third-party integrations