Learn moreKontent.ai Horizons is back! Secure your free spot today.
Petal

The all new JavaScript SDKs—should you upgrade?

This fall, we refactored and published the delivery and management JavaScript SDKs. What are the benefits, and are they good enough to justify a dependency upgrade in your project?


Ondrej PolesnyDec 14, 2021

In this article, I’ll introduce the new SDKs for JavaScript and explain the most important updates they bring and whether it’s a good idea to upgrade your projects.

So let’s start with the Delivery SDK.

JavaScript Delivery SDK v11

The previous versions of the Delivery SDK were working great feature-wise. But the new frameworks and industry trends have created a couple of problems for the SDK.

It was originally built for both Node and browser environments, so it relied on Parse5 for rich text resolution. It also depended on RxJS and, as a result, even when minimized, the client bundle was fairly large. The SDK and model generator used JavaScript classes to work with content, so you couldn’t serialize the created objects and had to use TypeResolvers for every single class. That was really inconvenient with frameworks like Next.js.

With these points in mind, the new SDK:

  • Got rid of RxJS and Parse5 dependencies.
    But you can still parse rich texts. For Node environments, you just need an additional package.
  • Is one-third of the previous version size.
    When minimized, it’s around 25kB and therefore well suitable for client-side usage.
  • Uses types instead of classes.
    You can directly serialize and deserialize the retrieved objects:
const blogPosts = await deliveryClient
  .getItems<BlogPost>()
  .type("blogPost")
  .toPromise()
const serialized = JSON.stringify(blogPosts.data.items)
const deserialized = JSON.parse(serialized)

Even if you don’t plan to handle the serialization yourself, frameworks like Next.js do it internally. With the new SDK, you simply don’t need to think about it, and it will work.
Using types also allowed us to completely remove TypeResolvers and make the DeliveryClient in it so much cleaner and more readable:

Kontent.ai
Kontent.ai
  • Comes with improved rich text resolution.
    The resolvers are no longer hidden in class definitions. You get direct and isolated control over the rendered content on the rich text element level:
const resolvedContent = createRichTextHtmlResolver().resolveRichText({
  element: blogPost.item.elements.content,
  linkedItems: linkedItemsHelper.convertLinkedItemsToArray(blogPost.linkedItems),
  contentItemResolver: (codename, contentItem) => {
    if (contentItem.system.type === projectModel.contentTypes.block_with_image.codename) {
      const block = contentItem as BlockWithImage
      return {
        contentItemHtml: `<section ...><img src="${block.elements.image.value[0].url" ... /></section>`
      }
    }
  }
})
  • Provides content model structure via Model Generator.
    Your content queries no longer need string literals or magic constants for codenames. The model generator will output both types and content model structure that contains all codenames:
// get latest 3 blog posts
const blogPosts = deliveryClient
  .items<BlogPost>()
  .type(projectModel.contentTypes.blogPost.codename)
  .orderByDescending(`elements.${projectModel.contentTypes.blogPost.elements.date.codename}`)
  .limitParameter(3)

JavaScript Management SDK v1.7

The Management SDK shares the dependency on the kontent-core package with the Delivery SDK, so the related benefits apply here too. The SDK bundle is smaller, no longer needs RxJS and Parse5, and uses types instead of classes. But there are also other improvements:

  • Support of collections management
    You can now list and modify collections:
const response = await managementClient.listCollections.toPromise()
console.log(response.data.collections)

// update collection name
const collection = response.data.collections[0]
await getTestClientWithJson(responseJson)
            .setCollections()
            .withData([
                {
                    op: "replace",
                    "property_name": "name",
                    value: "Updated collection",
                    reference: {
                        codename: collection.codename
                    }
                }
            ])
            .toPromise();

Note: See Kontent docs for details on working with collections in Management API

  • Searchable values on custom elements
    Custom elements store various types of data, like GPS coordinates, in various formats, like JSON or XML. However, it may be beneficial to let content editors find content items based on a specific string describing the custom elements’ data. In this example, we’re storing the street and city among the GPS coordinates solely for the purpose of searching:
const response = await managementClient.upsertLanguageVariant()
  .byItemCodename('central_perk')
  .byLanguageCodename('en-US')
  .withData((builder) => [
    ...
    builder.customElement({
      element: {
        codename: 'gps_coordinates'
      },
      value: '40.732413228351874,-74.00535081876384',
      searchable_value: '90 Bedford St, New York'
    }),
  ])
  .toPromise();
  • Subpages element
    If you’re using Web Spotlight, you need to use Subpages element to build the website content tree. The SDK now supports the ISubpagesElement and you can use it the same way as the linked items element.
  • Uploading assets via URL
    Often during migrations, the scripts needed to download assets and upload them to Kontent from local storage. Now, you can upload assets from URLs directly:
await managementClient
    .uploadAssetFromUrl()
    .withData({
        asset: { ... },
        binaryFile: { filename: 'warrior.jpg' },
        fileUrl: 'https://upload.wikimedia.org/wikipedia/en/e/e3/Warrior_Poster.jpg'
    })
    .toPromise();

Note: You can check more info in the SDK Readme on GitHub.

And remember, all these improvements are also available in the Kontent CLI :-)

Conclusion

In this article, I introduced the major improvements in the Delivery and Management JavaScript SDKs including a few code samples. Do you think that the performance and developer experience benefits are worth upgrading?

Just imagine that you remove all TypeResolvers, codename constant, and easily serialize all content in your project. Sounds good, right? :-)

Upgrade the dependencies:

npm i @kentico/kontent-delivery@latest
npm i @kentico/kontent-management@latest

Make sure to bookmark the Develop JavaScript Apps overview page, the best gateway into all Kontent resources, and join us on Discord because, hey, we want to hear about your project!

Written by

Ondrej Polesny

As Developer Evangelist, I specialize in the impossible. When something is too complicated, requires too much effort, or is just simply not possible, just give me a few days and we will see :).

More articles from Ondrej