@contentful/experiences-svelte 0.5.1 → 0.5.3

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,23 @@
1
+ ## 0.5.3 (2026-08-10)
2
+
3
+ ### 🧱 Updated Dependencies
4
+
5
+ - Updated client to 0.3.2
6
+ - Updated design to 0.7.2
7
+ - Updated core to 0.7.2
8
+
9
+ ## 0.5.2 (2026-08-07)
10
+
11
+ ### 🚀 Features
12
+
13
+ - server-side design pre-resolution against a fallback viewport [AIS-386] ([#119](https://github.com/contentful/experiences/pull/119))
14
+
15
+ ### 🧱 Updated Dependencies
16
+
17
+ - Updated client to 0.3.1
18
+ - Updated design to 0.7.1
19
+ - Updated core to 0.7.1
20
+
1
21
  ## 0.5.1 (2026-08-07)
2
22
 
3
23
  ### 🚀 Features
package/README.md CHANGED
@@ -42,7 +42,7 @@ useActiveViewport; // Rune-backed reactive object; you'll rarely need it directl
42
42
  ### Styling + runtime context (helpers)
43
43
 
44
44
  ```ts
45
- getDesignValues<T>(); // Resolved design values for the current node; read in a $derived to stay reactive
45
+ getDesignValues<T>(); // Optional helper: the same resolved design record that auto-fills props; read in a $derived to stay reactive
46
46
  toCss(design, options?); // Turns a design record into a plain style object, keeping only real CSS keys
47
47
  getExperience(); // RenderContext: debug, metadata, viewports, activeViewport
48
48
  getContentfulComponent(); // Raw payload for the enclosing node (or undefined)
@@ -50,7 +50,7 @@ getContentfulExperienceTemplate(); // Same, for the page-level Experience Templa
50
50
  type ToCssOptions;
51
51
  ```
52
52
 
53
- Design is **not** injected as props; components read it via `getDesignValues()` from the top of their `<script>` block. Token resolution is configured with `resolveToken` on your `Config` (`type ResolveToken`).
53
+ Resolved design values (viewport-cascaded + token-resolved server-side) are **auto-filled onto your component's props** by key, alongside content. Styling straight from `$props()` is the recommended path; `getDesignValues()` exposes the same record (read it in a `$derived` to stay reactive) for cases props don't cover. Token resolution is configured with `resolveToken` on your `Config` (`type ResolveToken`).
54
54
 
55
55
  ### Re-exported types and utilities
56
56
 
@@ -76,18 +76,21 @@ isCssProperty, toCssKey, CSS_PROPERTIES
76
76
  ## Quick reference
77
77
 
78
78
  ```svelte
79
- <!-- Button.svelte: content via props, design via the helper -->
79
+ <!-- Button.svelte: content + resolved design both arrive as props -->
80
80
  <script lang="ts">
81
- import { getDesignValues, toCss } from '@contentful/experiences-svelte';
82
-
83
- let { label = 'Button', url }: ButtonProps = $props();
84
- const design = $derived(getDesignValues());
85
- const style = $derived(toCss(design));
81
+ interface ButtonProps {
82
+ label?: string;
83
+ url?: string;
84
+ backgroundColor?: string; // resolved design, auto-filled
85
+ color?: string;
86
+ }
87
+
88
+ let { label = 'Button', url, backgroundColor, color }: ButtonProps = $props();
86
89
  </script>
87
90
  {#if url}
88
- <a href={url} style={style}>{label}</a>
91
+ <a href={url} style="background: {backgroundColor}; color: {color};">{label}</a>
89
92
  {:else}
90
- <button type="button" style={style}>{label}</button>
93
+ <button type="button" style="background: {backgroundColor}; color: {color};">{label}</button>
91
94
  {/if}
92
95
  ```
93
96
 
@@ -54,6 +54,7 @@
54
54
  viewports: experience?.viewports ?? [],
55
55
  activeViewport: experience?.viewports[0] ?? FALLBACK_VIEWPORT,
56
56
  activeViewportIndex: 0,
57
+ fallbackViewportIndex: experience?.fallbackViewportIndex ?? 0,
57
58
  });
58
59
 
59
60
  setExperience(liveContext);
@@ -64,6 +65,7 @@
64
65
  liveContext.viewports = experience.viewports;
65
66
  liveContext.activeViewport = experience.viewports[idx] ?? FALLBACK_VIEWPORT;
66
67
  liveContext.activeViewportIndex = idx;
68
+ liveContext.fallbackViewportIndex = experience.fallbackViewportIndex;
67
69
  liveContext.debug = debug;
68
70
  liveContext.metadata = { ...DEFAULT_CONTEXT.metadata, ...(metadata ?? {}) };
69
71
  });
@@ -1 +1 @@
1
- {"version":3,"file":"ClientExperienceRenderer.svelte.d.ts","sourceRoot":"","sources":["../src/ClientExperienceRenderer.svelte.ts"],"names":[],"mappings":"AAyFA,QAAA,MAAM,wBAAwB,kGAAwC,CAAC;AACvE,KAAK,wBAAwB,GAAG,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAC5E,eAAe,wBAAwB,CAAC"}
1
+ {"version":3,"file":"ClientExperienceRenderer.svelte.d.ts","sourceRoot":"","sources":["../src/ClientExperienceRenderer.svelte.ts"],"names":[],"mappings":"AA2FA,QAAA,MAAM,wBAAwB,kGAAwC,CAAC;AACvE,KAAK,wBAAwB,GAAG,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAC5E,eAAe,wBAAwB,CAAC"}
@@ -1,11 +1,11 @@
1
1
  import { render } from '@testing-library/svelte';
2
2
  import { describe, expect, it } from 'vitest';
3
3
  import DebugExperience from './DebugExperience.svelte';
4
- const emptyPlan = { nodes: [], viewports: [] };
4
+ const emptyPlan = { nodes: [], viewports: [], fallbackViewportIndex: 0 };
5
5
  function node(componentId, content = {}) {
6
6
  return {
7
7
  registration: { componentId },
8
- props: { content, design: {} },
8
+ props: { content, design: {}, designRaw: {} },
9
9
  slots: {},
10
10
  };
11
11
  }
@@ -25,7 +25,11 @@ describe('DebugExperience.svelte', () => {
25
25
  it('summarizes the node count, pluralizing correctly', () => {
26
26
  const { container: zero } = render(DebugExperience, { props: { experience: emptyPlan } });
27
27
  expect(zero.innerHTML).toContain('Experience debug — 0 top-level nodes');
28
- const one = { viewports: [], nodes: [node('button')] };
28
+ const one = {
29
+ viewports: [],
30
+ nodes: [node('button')],
31
+ fallbackViewportIndex: 0,
32
+ };
29
33
  const { container } = render(DebugExperience, { props: { experience: one } });
30
34
  expect(container.innerHTML).toContain('Experience debug — 1 top-level node');
31
35
  });
@@ -33,7 +37,11 @@ describe('DebugExperience.svelte', () => {
33
37
  const plan = {
34
38
  viewports: [],
35
39
  nodes: [],
36
- experienceTemplate: { experienceTemplateId: 'page', props: { content: {}, design: {} } },
40
+ experienceTemplate: {
41
+ experienceTemplateId: 'page',
42
+ props: { content: {}, design: {}, designRaw: {} },
43
+ },
44
+ fallbackViewportIndex: 0,
37
45
  };
38
46
  const { container } = render(DebugExperience, { props: { experience: plan } });
39
47
  expect(container.innerHTML).toContain('experience template: page');
@@ -42,6 +50,7 @@ describe('DebugExperience.svelte', () => {
42
50
  const plan = {
43
51
  viewports: [],
44
52
  nodes: [node('button', { label: 'Go' })],
53
+ fallbackViewportIndex: 0,
45
54
  };
46
55
  const { container } = render(DebugExperience, { props: { experience: plan } });
47
56
  expect(container.innerHTML).toContain('componentId');
@@ -51,7 +60,7 @@ describe('DebugExperience.svelte', () => {
51
60
  it('degrades a circular reference to a placeholder instead of throwing', () => {
52
61
  const n = node('button');
53
62
  n.props.resolved = { self: n.props };
54
- const plan = { viewports: [], nodes: [n] };
63
+ const plan = { viewports: [], nodes: [n], fallbackViewportIndex: 0 };
55
64
  expect(() => render(DebugExperience, { props: { experience: plan } })).not.toThrow();
56
65
  const { container } = render(DebugExperience, { props: { experience: plan } });
57
66
  expect(container.innerHTML).toContain('[Circular]');
@@ -7,9 +7,9 @@
7
7
  import type { Snippet } from 'svelte';
8
8
 
9
9
  import type { PortableRenderNode } from '@contentful/experiences-sdk-core';
10
- import { applyTokenResolver, resolveDesignProperties } from '@contentful/experiences-design';
11
10
 
12
11
  import { setContentfulComponent, setResolvedDesign } from './context.js';
12
+ import { selectResolvedDesign } from './design-utils.js';
13
13
  import type { RenderUnknown } from './component-props.js';
14
14
  import {
15
15
  normalizeComponentRegistration,
@@ -35,21 +35,20 @@
35
35
  componentId: node.registration.componentId,
36
36
  nodeId: node.nodeId,
37
37
  content: node.props.content,
38
- design: node.props.design,
38
+ design: node.props.designRaw,
39
39
  resolved: node.props.resolved,
40
40
  slots: node.slots,
41
41
  };
42
42
  setContentfulComponent(contentful);
43
43
 
44
- // Cascade design + resolve tokens; published on context for getDesignValues(),
45
- // never merged into props.
46
44
  const tokenResolvedDesign = $derived.by(() => {
47
- const resolvedDesign = resolveDesignProperties(
48
- node.props.design,
45
+ const { props, unresolved } = selectResolvedDesign(
46
+ node.props,
49
47
  experience.viewports,
50
- experience.activeViewportIndex
48
+ experience.activeViewportIndex,
49
+ experience.fallbackViewportIndex,
50
+ config.resolveToken
51
51
  );
52
- const { props, unresolved } = applyTokenResolver(resolvedDesign, config.resolveToken);
53
52
  if (unresolved.length && typeof console !== 'undefined') {
54
53
  console.warn(
55
54
  `[@contentful/experiences-svelte] resolveToken returned undefined for token id(s) on "${node.registration.componentId}": ${unresolved.join(', ')}. getDesignValues() will omit those keys.`
@@ -60,10 +59,12 @@
60
59
 
61
60
  setResolvedDesign(() => tokenResolvedDesign);
62
61
 
62
+ // Merge precedence (last wins): defaults < design < content < resolveData < children.
63
63
  const composed = $derived.by(() => {
64
64
  if (!componentConfig) return null;
65
65
  return {
66
66
  ...componentConfig.defaults,
67
+ ...tokenResolvedDesign,
67
68
  ...node.props.content,
68
69
  ...node.props.resolved,
69
70
  children,
@@ -1 +1 @@
1
- {"version":3,"file":"NodeRenderer.svelte.d.ts","sourceRoot":"","sources":["../src/NodeRenderer.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAI3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAGH,KAAK,MAAM,EACX,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAGpB,UAAU,iBAAiB;IACzB,IAAI,EAAE,kBAAkB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,aAAa,CAAC;IAC1B,aAAa,EAAE,aAAa,CAAC;IAC7B,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAoEH,QAAA,MAAM,YAAY,uDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
1
+ {"version":3,"file":"NodeRenderer.svelte.d.ts","sourceRoot":"","sources":["../src/NodeRenderer.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAI3E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAGH,KAAK,MAAM,EACX,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAGpB,UAAU,iBAAiB;IACzB,IAAI,EAAE,kBAAkB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,aAAa,CAAC;IAC1B,aAAa,EAAE,aAAa,CAAC;IAC7B,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAqEH,QAAA,MAAM,YAAY,uDAAwC,CAAC;AAC3D,KAAK,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AACpD,eAAe,YAAY,CAAC"}
@@ -51,6 +51,7 @@
51
51
  viewports,
52
52
  activeViewport: experience?.viewports[idx] ?? FALLBACK_VIEWPORT,
53
53
  activeViewportIndex: idx,
54
+ fallbackViewportIndex: experience?.fallbackViewportIndex ?? 0,
54
55
  };
55
56
  }
56
57
 
@@ -1 +1 @@
1
- {"version":3,"file":"ServerExperienceRenderer.svelte.d.ts","sourceRoot":"","sources":["../src/ServerExperienceRenderer.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AAqE1E,QAAA,MAAM,wBAAwB,mEAAwC,CAAC;AACvE,KAAK,wBAAwB,GAAG,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAC5E,eAAe,wBAAwB,CAAC"}
1
+ {"version":3,"file":"ServerExperienceRenderer.svelte.d.ts","sourceRoot":"","sources":["../src/ServerExperienceRenderer.svelte.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AAsE1E,QAAA,MAAM,wBAAwB,mEAAwC,CAAC;AACvE,KAAK,wBAAwB,GAAG,UAAU,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAC5E,eAAe,wBAAwB,CAAC"}
@@ -9,9 +9,9 @@
9
9
  import type { Snippet } from 'svelte';
10
10
 
11
11
  import type { PortableExperienceTemplate } from '@contentful/experiences-sdk-core';
12
- import { applyTokenResolver, resolveDesignProperties } from '@contentful/experiences-design';
13
12
 
14
13
  import { setContentfulExperienceTemplate, setResolvedDesign } from './context.js';
14
+ import { selectResolvedDesign } from './design-utils.js';
15
15
  import {
16
16
  normalizeExperienceTemplateRegistration,
17
17
  type ContentfulExperienceTemplate,
@@ -34,7 +34,7 @@
34
34
  setContentfulExperienceTemplate({
35
35
  experienceTemplateId: experienceTemplate.experienceTemplateId,
36
36
  content: experienceTemplate.props.content,
37
- design: experienceTemplate.props.design,
37
+ design: experienceTemplate.props.designRaw,
38
38
  resolved: experienceTemplate.props.resolved,
39
39
  } satisfies ContentfulExperienceTemplate);
40
40
  }
@@ -44,12 +44,13 @@
44
44
 
45
45
  const tokenResolvedDesign = $derived.by(() => {
46
46
  if (!experienceTemplate) return {};
47
- const resolvedDesign = resolveDesignProperties(
48
- experienceTemplate.props.design,
47
+ const { props, unresolved } = selectResolvedDesign(
48
+ experienceTemplate.props,
49
49
  experience.viewports,
50
- experience.activeViewportIndex
50
+ experience.activeViewportIndex,
51
+ experience.fallbackViewportIndex,
52
+ config.resolveToken
51
53
  );
52
- const { props, unresolved } = applyTokenResolver(resolvedDesign, config.resolveToken);
53
54
  if (unresolved.length && typeof console !== 'undefined') {
54
55
  console.warn(
55
56
  `[@contentful/experiences-svelte] resolveToken returned undefined for token id(s) on experience template "${experienceTemplate.experienceTemplateId}": ${unresolved.join(', ')}. getDesignValues() will omit those keys.`
@@ -58,13 +59,15 @@
58
59
  return props;
59
60
  });
60
61
 
61
- // A getter (not a snapshot) so getDesignValues() stays reactive; not merged into props.
62
+ // A getter (not a snapshot) so getDesignValues() stays reactive.
62
63
  setResolvedDesign(() => tokenResolvedDesign);
63
64
 
65
+ // Same precedence as component nodes.
64
66
  const composed = $derived.by(() => {
65
67
  if (!experienceTemplate || !experienceTemplateConfig) return null;
66
68
  return {
67
69
  ...experienceTemplateConfig.defaults,
70
+ ...tokenResolvedDesign,
68
71
  ...experienceTemplate.props.content,
69
72
  ...experienceTemplate.props.resolved,
70
73
  };
@@ -1 +1 @@
1
- {"version":3,"file":"WrapWithExperienceTemplate.svelte.d.ts","sourceRoot":"","sources":["../src/WrapWithExperienceTemplate.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AAInF,OAAO,EAGH,KAAK,MAAM,EACX,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAGpB,UAAU,+BAA+B;IACvC,kBAAkB,EAAE,0BAA0B,GAAG,SAAS,CAAC;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,aAAa,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;CACnB;AA0EH,QAAA,MAAM,0BAA0B,qEAAwC,CAAC;AACzE,KAAK,0BAA0B,GAAG,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAChF,eAAe,0BAA0B,CAAC"}
1
+ {"version":3,"file":"WrapWithExperienceTemplate.svelte.d.ts","sourceRoot":"","sources":["../src/WrapWithExperienceTemplate.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEtC,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AAInF,OAAO,EAGH,KAAK,MAAM,EACX,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAGpB,UAAU,+BAA+B;IACvC,kBAAkB,EAAE,0BAA0B,GAAG,SAAS,CAAC;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,aAAa,CAAC;IAC1B,QAAQ,EAAE,OAAO,CAAC;CACnB;AA6EH,QAAA,MAAM,0BAA0B,qEAAwC,CAAC;AACzE,KAAK,0BAA0B,GAAG,UAAU,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAChF,eAAe,0BAA0B,CAAC"}
@@ -1,3 +1,11 @@
1
+ import type { DesignPropValue, ResolveToken, ViewportDef } from '@contentful/experiences-sdk-core';
2
+ export declare function selectResolvedDesign(props: {
3
+ design: Record<string, unknown>;
4
+ designRaw: Record<string, DesignPropValue>;
5
+ }, viewports: ViewportDef[], activeViewportIndex: number, fallbackViewportIndex: number, resolveToken: ResolveToken | undefined): {
6
+ props: Record<string, unknown>;
7
+ unresolved: string[];
8
+ };
1
9
  export interface ToCssOptions {
2
10
  /** Keys to skip, matched against the original record key. */
3
11
  exclude?: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"design-utils.d.ts","sourceRoot":"","sources":["../src/design-utils.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,KAAK,CACnB,MAAM,EAAE,MAAM,EACd,EAAE,OAAO,EAAE,OAAO,EAAE,GAAE,YAAiB,GACtC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAYjC"}
1
+ {"version":3,"file":"design-utils.d.ts","sourceRoot":"","sources":["../src/design-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAUnG,wBAAgB,oBAAoB,CAClC,KAAK,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;CAAE,EACtF,SAAS,EAAE,WAAW,EAAE,EACxB,mBAAmB,EAAE,MAAM,EAC3B,qBAAqB,EAAE,MAAM,EAC7B,YAAY,EAAE,YAAY,GAAG,SAAS,GACrC;IAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAM1D;AAED,MAAM,WAAW,YAAY;IAC3B,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,KAAK,CACnB,MAAM,EAAE,MAAM,EACd,EAAE,OAAO,EAAE,OAAO,EAAE,GAAE,YAAiB,GACtC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAYjC"}
@@ -1,4 +1,13 @@
1
- import { isCssProperty, toCssKey } from '@contentful/experiences-design';
1
+ import { applyTokenResolver, isCssProperty, resolveDesignProperties, toCssKey, } from '@contentful/experiences-design';
2
+ // Use the server-resolved `props.design` when the active viewport matches the
3
+ // fallback; otherwise recompute the cascade from raw `props.designRaw`.
4
+ export function selectResolvedDesign(props, viewports, activeViewportIndex, fallbackViewportIndex, resolveToken) {
5
+ if (activeViewportIndex === fallbackViewportIndex) {
6
+ return { props: props.design, unresolved: [] };
7
+ }
8
+ const resolvedDesign = resolveDesignProperties(props.designRaw, viewports, activeViewportIndex);
9
+ return applyTokenResolver(resolvedDesign, resolveToken);
10
+ }
2
11
  /**
3
12
  * Convert a design record into a plain style object, keeping only keys that
4
13
  * normalize to a known CSS property. Non-CSS keys (`variant`, `as`, …) and
@@ -154,17 +154,18 @@ describe('ServerExperienceRenderer', () => {
154
154
  };
155
155
  const planWithMissing = {
156
156
  viewports: VIEWPORTS,
157
+ fallbackViewportIndex: 0,
157
158
  nodes: [
158
159
  {
159
160
  nodeId: 'root',
160
161
  registration: { componentId: 'contentful-container' },
161
- props: { content: {}, design: {} },
162
+ props: { content: {}, design: {}, designRaw: {} },
162
163
  slots: {
163
164
  children: [
164
165
  {
165
166
  nodeId: 'ghost',
166
167
  registration: { componentId: 'NotRegistered' },
167
- props: { content: {}, design: {} },
168
+ props: { content: {}, design: {}, designRaw: {} },
168
169
  slots: {},
169
170
  },
170
171
  ],
@@ -242,6 +243,7 @@ describe('ServerExperienceRenderer', () => {
242
243
  };
243
244
  const planWithResolved = {
244
245
  viewports: VIEWPORTS,
246
+ fallbackViewportIndex: 0,
245
247
  nodes: [
246
248
  {
247
249
  nodeId: 'r',
@@ -249,6 +251,7 @@ describe('ServerExperienceRenderer', () => {
249
251
  props: {
250
252
  content: { value: 'fromContent' },
251
253
  design: {},
254
+ designRaw: {},
252
255
  resolved: { value: 'fromResolveData' },
253
256
  },
254
257
  slots: {},
@@ -450,7 +453,7 @@ describe('ServerExperienceRenderer — getContentfulComponent()', () => {
450
453
  });
451
454
  });
452
455
  describe('ServerExperienceRenderer — resolveToken', () => {
453
- it('passes DesignToken envelopes through the resolver before render', async () => {
456
+ it('passes DesignToken values through the resolver before render', async () => {
454
457
  const cfg = {
455
458
  components: { 'contentful-button': ButtonFixture },
456
459
  resolveToken: (ref) => (ref.value === 'color/surface/hero' ? '#4f39f6' : undefined),
@@ -471,7 +474,7 @@ describe('ServerExperienceRenderer — resolveToken', () => {
471
474
  expect(container.innerHTML).toContain('data-bg="#4f39f6"');
472
475
  expect(container.innerHTML).not.toContain('DesignToken');
473
476
  });
474
- it('warns and drops the key from the design bag when the resolver returns undefined', async () => {
477
+ it('warns and drops the key from the design values when the resolver returns undefined', async () => {
475
478
  const warn = vi.spyOn(console, 'warn').mockImplementation(() => { });
476
479
  const cfg = {
477
480
  components: { 'contentful-button': CapturingComponent },
@@ -495,7 +498,7 @@ describe('ServerExperienceRenderer — resolveToken', () => {
495
498
  expect(warn).toHaveBeenCalledWith(expect.stringContaining('contentful-button'));
496
499
  warn.mockRestore();
497
500
  });
498
- it('leaves envelopes untouched when no resolver is supplied', async () => {
501
+ it('leaves token values untouched when no resolver is supplied (backward-compatible)', async () => {
499
502
  const cfg = { components: { 'contentful-button': ButtonFixture } };
500
503
  const plan = await resolveExperience({
501
504
  viewports: VIEWPORTS,
@@ -510,8 +513,8 @@ describe('ServerExperienceRenderer — resolveToken', () => {
510
513
  const { container } = render(ServerExperienceRenderer, {
511
514
  props: { experience: plan, config: cfg },
512
515
  });
513
- // Svelte stringifies the envelope object into "[object Object]" on the
514
- // attribute — the point is that the raw envelope reaches the component
516
+ // Svelte stringifies the token object into "[object Object]" on the
517
+ // attribute — the point is that the raw token value reaches the component
515
518
  // unchanged, so the customer can inspect it or resolve it themselves.
516
519
  expect(container.innerHTML).toContain('data-bg="[object Object]"');
517
520
  });
@@ -535,17 +538,20 @@ describe('ServerExperienceRenderer — resolveToken', () => {
535
538
  nodes: [componentNode('item', { id: 'i', contentProperties: { value: 'ok' } })],
536
539
  };
537
540
  const plan = await resolveExperience(tplPayload, tplConfig);
538
- // Templates don't carry design props in the current XDA payload shape;
539
- // seed one on the resolved plan so we exercise the experienceTemplate path.
540
- plan.experienceTemplate.props.design = { cfBackground: dt('brand/canvas') };
541
+ // Experience Templates don't carry design props in the current XDA payload
542
+ // shape; seed a raw token on the resolved plan so we exercise the
543
+ // experienceTemplate path. Render at a non-fallback viewport (mobile ≠
544
+ // fallback index 0) so the adapter recomputes from the seeded raw design
545
+ // and runs resolveToken.
546
+ plan.experienceTemplate.props.designRaw = { cfBackground: dt('brand/canvas') };
541
547
  const { container } = render(ServerExperienceRenderer, {
542
- props: { experience: plan, config: tplConfig },
548
+ props: { experience: plan, config: tplConfig, initialViewportId: 'mobile' },
543
549
  });
544
550
  expect(container.innerHTML).toContain('data-bg="#111827"');
545
551
  });
546
552
  });
547
- describe('ServerExperienceRenderer — design values are not injected as props', () => {
548
- it('does NOT spread resolved design values onto component props', async () => {
553
+ describe('ServerExperienceRenderer — design values auto-fill props', () => {
554
+ it('spreads resolved design values onto component props by their raw key', async () => {
549
555
  const cfg = { components: { capture: CapturingComponent } };
550
556
  const plan = await resolveExperience({
551
557
  viewports: VIEWPORTS,
@@ -560,20 +566,39 @@ describe('ServerExperienceRenderer — design values are not injected as props',
560
566
  render(ServerExperienceRenderer, {
561
567
  props: { experience: plan, config: cfg },
562
568
  });
563
- const keys = Object.keys(captureSink[0].props);
564
- // Content still flows as a prop; design does not.
565
- expect(keys).toContain('label');
566
- expect(keys).not.toContain('cfBackgroundColor');
567
- expect(keys).not.toContain('cfPadding');
569
+ // Content flows as a prop, and design auto-fills props under its raw key.
570
+ expect(captureSink[0].props).toMatchObject({
571
+ label: 'keep me',
572
+ cfBackgroundColor: '#f00',
573
+ cfPadding: '10px',
574
+ });
568
575
  // The values are still readable through getDesignValues().
569
576
  expect(captureSink[0].designValues).toEqual({
570
577
  cfBackgroundColor: '#f00',
571
578
  cfPadding: '10px',
572
579
  });
573
580
  });
581
+ it('lets content override design on a key collision (content wins)', async () => {
582
+ const cfg = { components: { capture: CapturingComponent } };
583
+ const plan = await resolveExperience({
584
+ viewports: VIEWPORTS,
585
+ nodes: [
586
+ componentNode('capture', {
587
+ id: 'p',
588
+ // Same key in both channels: content must win.
589
+ contentProperties: { cfPadding: 'from-content' },
590
+ designProperties: { cfPadding: m('from-design') },
591
+ }),
592
+ ],
593
+ }, cfg);
594
+ render(ServerExperienceRenderer, {
595
+ props: { experience: plan, config: cfg },
596
+ });
597
+ expect(captureSink[0].props).toMatchObject({ cfPadding: 'from-content' });
598
+ });
574
599
  });
575
600
  describe('ServerExperienceRenderer — getDesignValues()', () => {
576
- it('returns the resolved design bag for the current node', async () => {
601
+ it('returns the resolved design values for the current node', async () => {
577
602
  const cfg = {
578
603
  components: { capture: CapturingComponent },
579
604
  resolveToken: (ref) => (ref.value === 'brand/primary' ? '#4f39f6' : undefined),
@@ -615,6 +640,46 @@ describe('ServerExperienceRenderer — getDesignValues()', () => {
615
640
  expect(captureSink[0].designValues).toEqual({ cfPadding: '12px' });
616
641
  });
617
642
  });
643
+ describe('ServerExperienceRenderer — server pre-resolved design values', () => {
644
+ const probePayload = {
645
+ viewports: VIEWPORTS,
646
+ nodes: [
647
+ componentNode('contentful-container', {
648
+ id: 'p',
649
+ designProperties: { cfPadding: vbv({ desktop: m('40px'), mobile: m('12px') }) },
650
+ }),
651
+ ],
652
+ };
653
+ it('consumes props.design as-is when the active viewport equals the fallback', async () => {
654
+ const plan = await resolveExperience(probePayload, config, { initialViewportId: 'mobile' });
655
+ // Tamper the precomputed values with a sentinel the cascade could never produce.
656
+ plan.nodes[0].props.design = { cfPadding: 'SENTINEL' };
657
+ const { container } = render(ServerExperienceRenderer, {
658
+ props: { experience: plan, config, initialViewportId: 'mobile' },
659
+ });
660
+ expect(container.innerHTML).toContain('data-padding="SENTINEL"');
661
+ });
662
+ it('recomputes from raw design properties when the active viewport differs from the fallback', async () => {
663
+ const plan = await resolveExperience(probePayload, config, { initialViewportId: 'mobile' });
664
+ plan.nodes[0].props.design = { cfPadding: 'SENTINEL' };
665
+ // Active viewport (desktop, idx 0) ≠ fallback (mobile, idx 2) → recompute.
666
+ const { container } = render(ServerExperienceRenderer, {
667
+ props: { experience: plan, config, initialViewportId: 'desktop' },
668
+ });
669
+ expect(container.innerHTML).toContain('data-padding="40px"');
670
+ expect(container.innerHTML).not.toContain('SENTINEL');
671
+ });
672
+ it('recomputes when the active viewport differs from the default fallback (viewport[0])', async () => {
673
+ const plan = await resolveExperience(probePayload, config);
674
+ // No fallback configured → pre-resolved against viewport[0] (desktop, idx 0).
675
+ expect(plan.fallbackViewportIndex).toBe(0);
676
+ // Active viewport is mobile (idx 2) ≠ fallback (idx 0) → recompute to 12px.
677
+ const { container } = render(ServerExperienceRenderer, {
678
+ props: { experience: plan, config, initialViewportId: 'mobile' },
679
+ });
680
+ expect(container.innerHTML).toContain('data-padding="12px"');
681
+ });
682
+ });
618
683
  describe('toCss (Svelte)', () => {
619
684
  it('converts bare (non-cf) CSS keys — the shape real payloads use', () => {
620
685
  expect(toCss({ fontSize: '20px', backgroundColor: '#4f39f6' })).toEqual({
package/dist/types.d.ts CHANGED
@@ -9,9 +9,9 @@ export type { ResolveContext, ResolveToken };
9
9
  * analytics on `nodeId`, rendering a raw-payload panel in preview, or
10
10
  * rendering non-`children` slots through the exported `<NodesRenderer />`.
11
11
  *
12
- * Design properties stay in their **raw envelope form** here (the same shape
13
- * `ctx.design` carries inside `resolveData`). The viewport-cascaded, token-
14
- * resolved values are what `getDesignValues()` returns.
12
+ * Design properties stay in their **raw discriminated form** here (the same
13
+ * shape `ctx.design` carries inside `resolveData`). The viewport-cascaded,
14
+ * token-resolved values are what `getDesignValues()` returns.
15
15
  */
16
16
  export interface ContentfulComponent {
17
17
  componentId: string;
@@ -46,12 +46,19 @@ export interface ContentfulExperienceTemplate {
46
46
  export interface RenderContext extends ExperienceContext {
47
47
  activeViewport: ViewportDef;
48
48
  activeViewportIndex: number;
49
+ /**
50
+ * Viewport index the server pre-resolved design against (from
51
+ * `PortableRenderPlan.fallbackViewportIndex`). Renderers use `props.design`
52
+ * as-is when `activeViewportIndex` matches, and recompute otherwise. Always a
53
+ * number — the plan field is required, so the match is a real comparison.
54
+ */
55
+ fallbackViewportIndex: number;
49
56
  }
50
57
  /**
51
58
  * Customer-supplied configuration for a single component type. The `component`
52
- * receives the merged prop bag (content + resolveData + `children` Snippet).
53
- * Design values are not injected — a component reads them via
54
- * `getDesignValues()`. Runtime context and raw payload come from
59
+ * receives the merged props (design + content + resolveData + `children`
60
+ * Snippet); resolved design values auto-fill matching props and are also
61
+ * readable via `getDesignValues()`. Runtime context and raw payload come from
55
62
  * `getExperience()` / `getContentfulComponent()`.
56
63
  */
57
64
  export interface ComponentConfig<Props extends object = Record<string, unknown>> {
@@ -83,8 +90,8 @@ export interface Config {
83
90
  components: Components;
84
91
  experienceTemplates?: ExperienceTemplates;
85
92
  /**
86
- * Resolves `DesignToken` envelopes to runtime values before they reach a
87
- * component. If omitted, envelopes pass through unchanged. See `ResolveToken`
93
+ * Resolves `DesignToken` values to runtime values before they reach a
94
+ * component. If omitted, they pass through unchanged. See `ResolveToken`
88
95
  * in `@contentful/experiences-sdk-core` for the full contract.
89
96
  */
90
97
  resolveToken?: ResolveToken;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/experiences-svelte",
3
- "version": "0.5.1",
3
+ "version": "0.5.3",
4
4
  "description": "Svelte adapter for Contentful Experiences — Server and Client renderers over a PortableRenderPlan",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -35,9 +35,9 @@
35
35
  "check": "svelte-check --tsconfig ./tsconfig.json"
36
36
  },
37
37
  "dependencies": {
38
- "@contentful/experiences-client": "0.3.0",
39
- "@contentful/experiences-sdk-core": "0.7.0",
40
- "@contentful/experiences-design": "0.7.0"
38
+ "@contentful/experiences-client": "0.3.2",
39
+ "@contentful/experiences-sdk-core": "0.7.2",
40
+ "@contentful/experiences-design": "0.7.2"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "svelte": "^5.55.7"