Install
Works with Drupal: ^10.3 || ^11Using Composer to manage Drupal site dependencies
Alternative installation files
Release notes
Security
- sdx_router's content-scope response cache is keyed on the concrete path and the user, not just the route name and roles: two entities sharing a route (/taxonomy/term/1 vs /taxonomy/term/2) or two users with equal roles on a per-user view could be served each other's _dataProvider props within the 60s TTL. The SPA VIEW fast path now merges the page renderer's collected cacheability into its response, varies by user, and is uncacheable when the payload carries flash messages.
Fixed
- sdx:resolve reports peer-dependency mismatches before any install. The registry cache keeps each version's peerDependencies, and after pinning the resolver checks every package's peer ranges against the pinned set: a plugin whose peer range excludes the pinned framework version (the shape of #3617527 -> a Vite 5/6 plugin next to Vite 7) is printed as a peer_mismatch resolution note in sdx:resolve (also --dry-run) and sdx:status, and logged. Advisory rather than fatal: pnpm installs such a tree with a warning and sites run that way today, while npm refuses at install time, where the note now explains why. Peers nobody pins are left to the package manager.
- Builds are atomic. The Vite bundler used to build straight into the live dist with emptyOutDir, deleting the chunk files pages still referenced for the duration of the build, and a failed vendor build left a dist with fresh chunks and no runtime. Each framework now builds into a sibling staging directory (component chunks and vendor bundle alike) that is renamed into place only when every step succeeded; on failure the staging directory is discarded and the live dist is untouched. The previous build's content-hashed files are carried over for one build so pages served during the cache-invalidation window still resolve their chunk URLs. Builds of the same framework are serialised with a lock.
- Svelte components mount with their props again. sdx_svelte's mount adapter, rerender hook and entry stub instantiate components with the class API, which Svelte 5 no longer provides by default, every runes component threw "Cannot read properties of undefined" out of $props() and showed the error fallback. The framework plugin now compiles with compatibility componentApi 4, the adapter passes hydrate so SSR markup is made interactive instead of a second copy being appended, and the SSR renderer stub uses render() from svelte/server (kept external so it resolves to the same package the components were compiled against).
- The Vue mount adapter honours hydration: an SSR container is mounted with createSSRApp() over the existing markup instead of the markup being cleared and the app re-created.
Changed
- Core no longer imports the Vite bundler. sdx:test obtains its test-runner config through the new SdxBundlerPluginInterface::generateTestRunnerConfig() (Vite returns its Vitest config; other bundlers may return NULL) instead of type-hinting Drupal\sdx_vite\Service\ViteConfigGenerator, and the build manifest location comes from the bundler plugin definition's new manifest_path attribute property (.vite/manifest.json for Vite) instead of a literal in BuildOutputResolver, read from the definition so runtime paths never instantiate the bundler.
- The three framework modules' hook_page_attachments() share one core service, sdx.framework_page_attachments. React, Vue and Svelte each carried an identical copy of the mount-library / import-map / drupalSettings / dev-server logic, and fixes made to React never reached the copies: Vue built its vendor URL with dirname() (no per-file build fingerprint, so a rebuilt vendor bundle was not cache-busted) and fell back to esm.sh unconditionally in production. FrameworkPageAttachments::attach() now does it once, per-file fingerprints, CDN fallback only in dev mode or with
.settings cdn_fallback (new for sdx_vue, default off) and always logged, runtime.conditional honoured for every framework, browser aliases limited to .js/.mjs, the build manifest cache tag, and each hook declares only its vendor files and CDN URLs.