Migrate from SDK v1 to SDK v2
Overview
When migrating from Contentful Studio SDK v1 to SDK v2, you have to alter the code of your custom component to manually resolve field references.
When you’re creating a custom component you can bind two kinds of properties to it:
scalar
- for example.
Text
(prop passed to component isstring
)
- for example.
objects with references
Link
(prop passed to component is a JS object representing entry)Array
(prop passed to component is a JS Array holding entries, each of them is a JS-object)
In v1 of the SDK, the entities you would receive as props were automatically recursively resolved up to level 3, causing references to be sometimes underfetched or overfetched.
That's why, in v2 of the SDK we changed the mechanism of link resolution. Your components that have Array
or Link
props still receive objects representing entities, however, those entities will NOT have their links resolved. You can resolve any link within your component using the inMemoryEntities.maybeResolveLinks
utility method, as shown in the documentation.
How to migrate from SDK v1 to SDK v2
Use the following code snippet to migrate from SDK v1 to SDK v2:
import type { Asset, UnresolvedLink } from 'contentful';
import { inMemoryEntities } from '@contentful/experiences-sdk-react';
type ItemWithResolvedReferences = {
sys: {
id: string;
};
fields: {
title?: string;
description?: string;
image?: Asset; // resolved asset, as opposed to unresolved link
};
};
type ItemWithUnresolvedReferences = {
sys: {
id: string;
};
fields: {
title?: string;
description?: string;
image?: UnresolvedLink<'Asset'>; // unresolved link to an asset
};
};
type ItemWithManuallyResolvedReferences = Omit<ItemWithUnresolvedReferences, 'fields'> & {
fields: Omit<ItemWithUnresolvedReferences['fields'], 'image'> & {
image?: Asset; // manually resolved asset
};
};
type PropsV1 = {
item: ItemWithResolvedReferences;
};
type PropsV2 = {
item: ItemWithUnresolvedReferences;
};
// In SDK v1 the component receives an item, which is an Entry with resolved references.
// Thus the image field is already an asset, not link to an asset, and thus can be used immediately without resolution.
export const ComponentUsingSdkV1: React.FC<PropsV1> = ({ item }) => {
return (
<div>
<img src={item?.fields.image?.fields.file?.url as string} alt={item?.fields.title} />
<div>
<h3>{item?.fields.title}</h3>
<p>{item?.fields.description}</p>
<button> Explore </button>
</div>
</div>
);
};
// In SDK v2 the component receives an item, which is an Entry with unresolved references.
// Thus the image field is a link object, which needs to be replaced with the actual asset object.
export const ComponentUsingSdkV2: React.FC<PropsV2> = ({ item: itemWithUnresolvedReferences }) => {
// Must make copy! as `item` is marked as immutable by the SDK via Object.freeze().
const item: ItemWithManuallyResolvedReferences = structuredClone(itemWithUnresolvedReferences) as ItemWithManuallyResolvedReferences;
item.fields.image = inMemoryEntities.maybeResolveLink(item.fields.image) as Asset | undefined;
return (
<div>
<img src={item?.fields.image?.fields.file?.url as string} alt={item?.fields.title} />
<div>
<h3>{item?.fields.title}</h3>
<p>{item?.fields.description}</p>
<button> Explore </button>
</div>
</div>
);
};