Was this page helpful?

TypeScript in JavaScript client library

We rewrote our JavaScript client library in TypeScript to provide better type safety for users of contentful.js. Typescript support allows us to keep types constantly up-to-date. The following features are added:

  • Query type support—Autosuggestions based on your Contentful content model allow you to know exactly which search parameters you can use in your requests.

  • Chained client modifiers—An option to modify the response shape of your CDA calls, and thus get predictable response type support.

This tutorial walks you through some examples of these features' usage.

Prerequisites

To successfully work with TypeScript in contentful.js, you must be familiar with the JavaScript client library and have a basic TypeScript project set up in strict mode. To learn about the JavaScript client library, refer to Getting Started with Contentful and JavaScript.

NOTE: If you already have a project which is using the previous version of contentful.js, refer to Migrate from the old to the new version of contentful.js for migration instructions.

Query types

To understand how query type support works, let’s consider the following example:

Let’s say you need to query entries of a content type BlogPost which has several fields of different types. In the previous versions of contentful.js, when composing the query object to pass to getEntries, you would have to manually check which fields existed, and look up which operators out of multiple CDA search parameters are allowed for which field type.

With TypeScript, autosuggestions are dynamically displayed as you type the names of the fields, so you can select the ones you need from the drop-down.

The steps listed below explain how to query entries of our example content type BlogPost with TypeScript.

To query entries of a content type BlogPost:

  1. Define the shape of this content type as a TypeScript type or interface.
NOTE: We recommend to automate this step instead of doing it manually. To learn how to automatically generate types for your Contentful content models, refer to Generating type definitions for content types.
type BlogPostSkeleton =
{
  contentTypeId: "blogPost",
  fields: {
    productName: Contentful.EntryFieldTypes.Text,
    image: Contentful.EntryFieldTypes.Asset,
    price: Contentful.EntryFieldTypes.Number,
    categories: Contentful.EntryFieldTypes.Array<Contentful.EntryFieldTypes.EntryLink<CategorySkeleton>>,
  }
}
  1. Pass the type defined in step 1 to the getEntries call as a generic:
client.getEntries<BlogPostSkeleton>()

getEntries accepts a query object, which in turn accepts a variety of search parameters, depending on your content type's field names and types. To view all search parameters, refer to our CDA reference.

  1. Start typing a field’s name and all eligible search parameters will be suggested to you:
NOTE: With the previous contentful.js version, you had to remember or look up which parameters work for which field types and manually write them out:
client.getEntries<BlogPostSkeleton>({
  content_type: "blog_post",
  "fields.price[gt]": 100
})
NOTE: To learn more about Query type support, refer to our TypeScript reference in GitHub.

Chained client modifiers

Entries can be returned in six different response shapes, depending on your configuration regarding the following:

  • Link resolution—The response shape depends on whether the linked entries are intended to be resolved or not and actions to be taken towards unresolvable links.

  • Localisation—The response shape depends on whether an entry is returned in one specific locale or in all existing locales.

Types are supported for each of the response shapes.

To configure the desired response shape, you can use chained client modifiers. You can use just one, or combine several of them.

Let’s go back to our BlogPost example from above to illustrate how to work with chained client modifiers.

  1. Create the Contentful client to query content from the CDA:
const client = contentful.createClient({
  accessToken: "<you-access-token>",
  space: "<your-space-id>"
})

By default, when querying entries with this client, you receive the entries in your default locale, with linked entries being resolved:

const entries = await client.getEntries({
  content_type: "blog_post"
})
NOTE: Some links might not be resolvable, e.g. when a linked entry is not published yet. By default, such entries aren't removed, but are represented by a Link field.
  1. Use one or multiple chained modifiers according to the list and explanations below:
  • withAllLocales—Use this modifier to return your entries in all available locales:
const localizedEntries = await client.withAllLocales.getEntries({
  content_type: "blog_post"
})
  • withoutLinkResolution—Use this modifier to disable the automatic resolution of linked entries:
const localizedEntriesWithoutLinkResolution = await client.withAllLocales.withoutLinkResolution.getEntries({
  content_type: "blog_post"
})
  • withoutUnresolvableLinks—Use this modifier to keep link resolution enabled and to discard any links that are unresolvable:
const entriesWithoutUnresolvable = await client.withoutUnresolvableLinks.getEntries({
  content_type: "blog_post"
})
NOTE: To use the same configuration throughout your project, you can define the chain in the beginning and use it as such:
const baseClient = contentful.createClient({
  accessToken: "<you-access-token>",
  space: "<your-space-id>",
})

const client = baseClient.withAllLocales

const localizedEntries = await client.getEntries({
  content_type: "blog_post"
})

To learn more about chained client modifiers and which response types you get for each configuration, refer to our TypeScript reference in GitHub.

Migrate from the old to the new version of contentful.js

To learn how to migrate from an older version of contentful.js to version 10 of contentful.js with enhanced TypeScript support, read our migration guide.

Share your feedback

We are curious to hear your feedback! To share your thoughts about working with contentful.js with enhanced TypeScript support, please fill in the feedback form.