Skip to content

SDC Libraries

What: SDC JS that needs global scope (like AJAX overrides, document-level event listeners) should go in theme-level library overrides, not in the SDC's {component}.js file. SDC JS only loads when the component renders.

Rationale: Drupal lazy-loads SDC libraries — the JS file ships with the rendered HTML when (and only when) the component appears in the page. That's correct for component-scoped behavior (a button's click handler, a slider's init). It's wrong for global behavior (AJAX response handlers, body-level event listeners, polyfills) that must run on pages where the component isn't rendered.

When it applies: Whenever an SDC needs JS that operates outside its own DOM scope. Examples: an SDC that triggers Drupal AJAX commands needs the AJAX command handler available on every page, including pages without the component.

Example:

# Wrong — global handler in SDC library only loads when component renders
# components/search-bar/search-bar.component.yml
name: Search Bar
libraryDependencies:
  - core/drupal.ajax
js:
  search-bar.js: {}      # ← contains AJAX response override; only loads with component

# Right — split: component-scoped JS in SDC, global JS in theme library
# components/search-bar/search-bar.component.yml
name: Search Bar
js:
  search-bar.js: {}      # ← only the component's own click/init logic

# {theme}.libraries.yml
ajax-overrides:
  js:
    js/ajax-overrides.js: {}
  dependencies:
    - core/drupal.ajax

# {theme}.theme — attach globally
function {theme}_page_attachments(array &$attachments) {
  $attachments['#attached']['library'][] = '{theme}/ajax-overrides';
}