@speedkit/cli 3.20.0 → 3.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ # [3.21.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v3.20.0...v3.21.0) (2026-01-30)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **wizard:** soft to hard nav conversion ([501c490](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/501c49092a50d91a2b7986ffa41ea6916282c005))
7
+ * **wizard:** soft to hard nav conversion ([9801d0f](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/9801d0f90b6cbf4f2d895aed56483c505b84a8cc))
8
+
9
+
10
+ ### Features
11
+
12
+ * **customer-config:** prevent soft2hard nav conversion for product variant switches ([66c0923](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/66c0923a22e15965c26c11a0ae4370170ec4ccf5))
13
+ * **customer-config:** remove conditional for predictive preloading as it is not necessary ([eead957](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/eead957e2c8b3e094edd7204858c2cb87036c1e7))
14
+ * **customer-config:** update general logic for soft2hard nav conversion ([05a5a61](https://gitlab.orestes.info/baqend/speed-kit-cli/commit/05a5a611476b9dbda9d3afe22a15a7dc637d4d66))
15
+
1
16
  # [3.20.0](https://gitlab.orestes.info/baqend/speed-kit-cli/compare/v3.19.0...v3.20.0) (2026-01-06)
2
17
 
3
18
 
package/README.md CHANGED
@@ -21,7 +21,7 @@ $ npm install -g @speedkit/cli
21
21
  $ sk COMMAND
22
22
  running command...
23
23
  $ sk (--version)
24
- @speedkit/cli/3.20.0 linux-x64 node-v20.19.6
24
+ @speedkit/cli/3.21.0 linux-x64 node-v20.20.0
25
25
  $ sk --help [COMMAND]
26
26
  USAGE
27
27
  $ sk COMMAND
@@ -37,6 +37,7 @@ export interface CustomerConfigSettings {
37
37
  withGoogleOptimize?: boolean;
38
38
  activateCfRocketLoaderPlugin?: boolean;
39
39
  hasSoftNavigations?: boolean;
40
+ convertSoftToHardNavigations?: boolean;
40
41
  isPOV?: boolean;
41
42
  isShopify?: boolean;
42
43
  isShopware?: boolean;
@@ -136,7 +136,7 @@ class CustomerConfigService {
136
136
  return true;
137
137
  }
138
138
  async getConfigSettings() {
139
- let { production, staging, activateScopedDeployments, subRouteScope, includeServiceWorker, activateImageOptimisation, removeLazyLoading, addSSR, addSSRInnerShadowDomSupport, addDeviceDetection, useGATracking, useScrapingBee, withGoogleOptimize, activateCfRocketLoaderPlugin, hasSoftNavigations, isShopify, isShopware, isSalesforce, isOxid, isPlentymarkets, isPOV, } = {};
139
+ let { production, staging, activateScopedDeployments, subRouteScope, includeServiceWorker, activateImageOptimisation, removeLazyLoading, addSSR, addSSRInnerShadowDomSupport, addDeviceDetection, useGATracking, useScrapingBee, withGoogleOptimize, activateCfRocketLoaderPlugin, hasSoftNavigations, convertSoftToHardNavigations, isShopify, isShopware, isSalesforce, isOxid, isPlentymarkets, isPOV, } = {};
140
140
  this.appName = await this.cli.prompt(`[App Name] Enter desired SK app name:`, {
141
141
  validator: (input) => /^[\da-z]+(?:-[\da-z]+)*$/.test(input) ? "" : "No valid kebab-case",
142
142
  defaultAnswer: this.appName,
@@ -198,6 +198,9 @@ class CustomerConfigService {
198
198
  useGATracking = await this.cli.confirm("[Tracking] Add tracking based on Google Analytics' DataLayer?");
199
199
  }
200
200
  hasSoftNavigations = await this.cli.confirm("[Tracking] Add tracking for Soft Navigations?", false);
201
+ if (hasSoftNavigations) {
202
+ convertSoftToHardNavigations = await this.cli.confirm("[Soft2Hard Navigations] Should soft navigations be converted to hard navigations?", false);
203
+ }
201
204
  isPOV = await this.cli.confirm("[Tracking] Is a POV (proof of value) anticipated, so that additional tracking is needed?", false);
202
205
  withGoogleOptimize = await this.cli.confirm("[Services] Is Google Optimize used?", false);
203
206
  activateCfRocketLoaderPlugin = await this.cli.confirm("[Services] Is Cloudflare's Rocket Loader used, for which we need to activate our rocket loader plugin?", false);
@@ -218,6 +221,7 @@ class CustomerConfigService {
218
221
  withGoogleOptimize,
219
222
  activateCfRocketLoaderPlugin,
220
223
  hasSoftNavigations,
224
+ convertSoftToHardNavigations,
221
225
  isShopify,
222
226
  isShopware,
223
227
  isSalesforce,
@@ -269,6 +269,22 @@ import { PredictivePreloading } from 'predictive-preloading/predictivePreloading
269
269
  },
270
270
  {{/if}}
271
271
  {{/if}}
272
+ {{#if convertSoftToHardNavigations}}
273
+ {
274
+ on: "domInteractive",
275
+ track: () => {
276
+ if (
277
+ // check that dashboard is not disabled and user is in group A
278
+ window?.SpeedKit.lastNavigate.disconnectCause.indexOf("DashboardDisabled") > -1 ||
279
+ !window?.SpeedKit?.skSupported ||
280
+ SpeedKit.group !== "A"
281
+ ) {
282
+ return;
283
+ }
284
+ convertSoftToHardNavigation();
285
+ },
286
+ },
287
+ {{/if}}
272
288
  {{#if isPlentymarkets}}
273
289
  {
274
290
  on: "domInteractive",
@@ -367,12 +383,81 @@ import { PredictivePreloading } from 'predictive-preloading/predictivePreloading
367
383
  });
368
384
  {{/if}}
369
385
 
370
- {{#if hasSoftNavigations}}
371
- new PredictivePreloading({
372
- // TODO: configure according to the needs of the customer e.g. preload API-calls, soft-nav to hard-nav conversion...
373
- });
374
- {{else}}
386
+ {{#if convertSoftToHardNavigations}}
387
+ function softNavShouldBeConverted(url) {
388
+ // no link item found
389
+ if (!url || url === location.href) {
390
+ return false;
391
+ }
392
+
393
+ try {
394
+ // Always resolve the target relative to the current location
395
+ var resolvedTarget = new URL(url, location.href);
396
+
397
+ if (location.origin !== resolvedTarget?.origin) {
398
+ return false;
399
+ }
400
+
401
+ // must be a different path
402
+ if (location.pathname === resolvedTarget?.pathname) {
403
+ return false;
404
+ }
405
+
406
+ if (!SpeedKit?.isPageTypeEnabled(resolvedTarget.href)) {
407
+ return false;
408
+ }
409
+
410
+ if (
411
+ // speedKit sw is known
412
+ window?.speedKit?.sw &&
413
+ // can detect sw
414
+ navigator?.serviceWorker?.controller?.scriptURL &&
415
+ navigator.serviceWorker.controller.scriptURL.indexOf(new URL(window.speedKit.sw, location.origin).pathname) > -1
416
+ ) {
417
+ return true;
418
+ }
419
+ } catch (e) {}
420
+ return false;
421
+ }
422
+
423
+ function convertSoftToHardNavigation() {
424
+ function speedKitClickEventListener(event) {
425
+ var target = event.target.closest("a");
426
+
427
+ // Drop out if no link address is found or the target is the current page
428
+ if (!target || !target.href || target.href === location.href) {
429
+ return;
430
+ }
431
+
432
+ // Don't convert to hard navigation if it is just a product variant switch
433
+ // TODO: adjust conditions to customer-specific implementation as needed
434
+ var targetPathname = new URL(target.href).pathname;
435
+ var isPDP = targetPathname.indexOf("/p/") !== -1;
436
+ var isSamePathname = new URL(location.href).pathname === targetPathname;
437
+ var variantSwitchIdentifier = target.matches('.color-option, .size-option, .swatch-option');
438
+ if (
439
+ (isPDP && isSamePathname) || // url-based check
440
+ variantSwitchIdentifier // element-based check
441
+ ) {
442
+ return;
443
+ }
444
+
445
+ // Check if the target is enabled by SpeedKit and is a valid page for conversion
446
+ if (!softNavShouldBeConverted(target?.href)) {
447
+ return;
448
+ }
449
+
450
+ // Prevent soft navigation
451
+ event.preventDefault();
452
+
453
+ // Execute hard navigation instead
454
+ location.href = target.href;
455
+ }
456
+ window.addEventListener("click", speedKitClickEventListener, true);
457
+ }
458
+
459
+ {{/if}}
460
+
375
461
  // TODO: check if prerendering needs to be scoped to certain pages
376
462
  new PredictivePreloading({ prerender: true });
377
- {{/if}}
378
463
  }();
@@ -738,5 +738,5 @@
738
738
  ]
739
739
  }
740
740
  },
741
- "version": "3.20.0"
741
+ "version": "3.21.0"
742
742
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@speedkit/cli",
3
3
  "description": "Speed Kit CLI",
4
- "version": "3.20.0",
4
+ "version": "3.21.0",
5
5
  "author": {
6
6
  "name": "Baqend.com",
7
7
  "email": "info@baqend.com"