Install

Works with Drupal: ^10.3 || ^11

Using Composer to manage Drupal site dependencies

Alternative installation files

Download tar.gz 751.37 KB
MD5: 4ce53bcb97b147a4355bf629ab57958e
SHA-1: e831fdeea506d18fb2dd15911560d4d9b8470739
SHA-256: b45b7cac9605635e303259d091fcc3ca26b9f963f0c2a86fb20dd0657702d8af
Download zip 1.26 MB
MD5: 976423a6808fa7001f40698cbf1875ab
SHA-1: c0bcf94f1d7efea4c41117096519c4ac38fb19d6
SHA-256: 2f1075ff38a9ca68713eebd5c4239fabd2b931013c094a2fd764f32026b0168d

Release notes

Added
- Opt-in per-page asset scoping behind three new sdx.settings groups (all off by default):
css.scoped attaches owner-scoped CSS per component, runtime.conditional attaches the mount
runtime only on pages rendering an SDX component, chunking.* coalesces many-tiny-module
packages (icon sets) into one chunk per extension set.
- SSR watch mode: drush sdx:ssr:build --watch rebuilds bundles incrementally, and
ssr-server.mjs --watch (or SDX_SSR_WATCH=1) hot-reloads on dist changes - no rebuild or
server restart in the dev loop. Not for production.
- sdx:ssr:build now emits the framework renderer module, so out-of-process SSR sidecars can
start ssr-server.mjs --renderer without calling back into Drupal.
- The mount runtime reports containers no framework claims (data-sdx-map-miss / console
warning) instead of skipping them silently.
- Position-independent vitest config plus drush sdx:test --print-config, enabling component
suites in CI from a bare checkout; @testing-library/user-event ships with the toolchain.
- A project-root tsconfig.json shim is generated for editors, eliminating phantom IDE errors;
esbuild transform options are pinned so the bundler never picks the shim up.
- Status report warns when built artifacts disagree with the stored build_mode.
- sdx_react: hydration mounts log the component stack via onRecoverableError.

Changed
- The esm.sh CDN fallback for a missing React vendor bundle is no longer silent or
unconditional: vendor build failures fail the build, the fallback needs dev mode or the new
sdx_react.settings cdn_fallback opt-in, always logs, can never change React majors, and a
status-report row explains the state.
- Drush surface cleanup: the duplicate sdx:doctor / sdx:list registrations are resolved - the
dependency pair is now sdx:deps:doctor / sdx:deps:list (update scripts using the old
variants); dash-style aliases (sdx-resolve, sdx-ssr-build, ...) added across the surface;
build and install paths unified.
- The drupalSettings browser-URL map is per-mount instead of a full per-framework table;
client-injected mounts (overlays, dialogs) opt in via sdx.expose_url: true.
- DRAST page payloads are cacheable: per-session fields (user name, flash messages) moved to a
placeholdered data-sdx-session-envelope script consumed once after hydration.
- Widget scaffolds hand props to the mount pipeline in memory instead of duplicating them in a
script sidecar (tens of KB saved on component-heavy pages).
- Vendor bundles carry real static named exports instead of post-build patching; all inline JS
codegen moved to reviewable stub files.
- sdx:resolve is lockfile-aware (repeat resolves are reproducible); only sdx:update re-pins.
- sdx:create's picker only offers scaffoldable site-owned extensions (no more scaffolding into
core/contrib; custom sdx_*-named modules are eligible again).
- drupalSettings.sdx.route_patterns is declaration-based and empty by default (declare routes
in .component.yml under sdx.routes).
- TypeScript strict type-check driven to zero errors; the generated tsconfig is accurate
enough that sdx:ts:type-check reports real errors.
- Canonical first-install flow is drush en sdx && drush sdx:init && drush sdx:resolve; stale
sdx:pm:install references updated.
- generateCssSourceWrapper() dropped its unused $output_dir parameter (subclasses beware).

Fixed
- Mutable build-artifact URLs (mount.js, vendor bundles) carry mtime fingerprints - a
returning browser no longer runs a stale mount runtime against fresh markup (one React #418
per widget, all widgets recovered empty).
- sdx:build produces working bundles for every enabled framework (Vue/Svelte alone or next to
React): file extensions propagate to the resolver and hook_sdx_aliases is scoped per
framework.
- SSR build and cross-framework mounts: Vue SFC style sub-requests no longer crash the SSR
build, SSR alias discovery is per-framework, and each framework's mount behavior only claims
containers in its own component map (no more 404s for the other framework's bundle).
- The SSR build skips themes on disk but not installed instead of aborting.
- pnpm 11: node-linker hoisting moved to pnpm-workspace.yaml; non-interactive installs no
longer abort on unreviewed transitive build scripts (they are skipped, never run).
- sdx:resolve heals a missing node_modules and names the missing package-manager module;
sdx:deps:doctor exits non-zero while the workspace is not ready.
- Enabling bare sdx without a bundler no longer bricks the whole drush surface (null
library-asset compiler registered by default).
- The generated Vite config handles the extended optional-alias hook_sdx_aliases shape.
- sdx:build:css writes its wrapper next to the source entry so PostCSS finds the extension's
config; sdx_postcss scans the owner extension's own components/ directory.
- sdx_router: SPA navigation across language variants no longer re-executes already-loaded
aggregates (which reset window.Drupal and wiped all behaviors); scripts keyed by pathname.
- sdx_router: SPA navigate no longer attaches on non-DRAST (e.g. Claro admin) pages.
- Co-located ComponentDataProvider plugins survive the plugin definition cache and APCu
negative autoloader lookups (was an intermittent "class does not exist" degradation).
- sdx:test collects colocated specs, scoped to SDX component providers only (no foreign
contrib test.js sweeps), also from alias-only extensions, and propagates vitest failures as
a non-zero exit.
- Build-pipeline file writes fail loud with role and path instead of leaving empty files for
Node to choke on.
- Uninstalling sdx deletes the orphaned sdx_typescript.settings config (reinstall no longer
fails on "config already exists").
- Degraded SSR renders are uncacheable; new page_ssr.strict setting fails closed with 503 +
Retry-After.
- Store-backed React hooks (useForm, usePage, usePresence, ...) can server-render
(getServerSnapshot supplied).
- Per-component SSR skipped for DRAST-tokenized elements, halving SSR work on uncached pages.
- Hydration commits at most one component per event-loop task - no more single long
main-thread task on pages with many eager SSR containers.
- The setup wizard references a shipped logo.svg instead of a 404ing logo.png.

Created by: vzsigmond
Created on: 9 Aug 2026 at 15:29 UTC
Last updated: 9 Aug 2026 at 15:30 UTC
Bug fixes
New features

Other releases