> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://contentful.com/developers/docs/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://contentful.com/_mcp/server. # TypeScript in JavaScript client library > This tutorial explains some examples of using JavaScript with TypeScript | query types | chained client modifiers. We rewrote our JavaScript client library in [TypeScript](https://www.typescriptlang.org/) 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](https://github.com/contentful/contentful.js) 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](/sdks/javascript/tutorials/using-js-cda-sdk). > **Info** > > 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](#migrate-from-the-old-to-the-new-version-of-contentfuljs) 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](/references/content-delivery-api/overview) 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. > **Info** > > 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](https://github.com/contentful/contentful.js/blob/master/TYPESCRIPT.md#generating-type-definitions-for-content-types). ```javascript type BlogPostSkeleton = { contentTypeId: "blogPost", fields: { productName: Contentful.EntryFieldTypes.Text, image: Contentful.EntryFieldTypes.Asset, price: Contentful.EntryFieldTypes.Number, categories: Contentful.EntryFieldTypes.Array>, } } ``` 2. Pass the type defined in step 1 to the `getEntries` call as a generic: ```javascript client.getEntries() ``` `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](/references/content-delivery-api/overview). 3. Start typing a field's name and all eligible search parameters will be suggested to you: > **Info** > > 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: `javascript client.getEntries({ content_type: "blog_post", "fields.price[gt]": 100 }) ` > **Info** > > To learn more about Query type support, refer to our [TypeScript reference](https://github.com/contentful/contentful.js/blob/master/TYPESCRIPT.md#query-types) 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: ```javascript const client = contentful.createClient({ accessToken: "", space: "" }) ``` By default, when querying entries with this client, you receive the entries in your default locale, with linked entries being resolved: ```javascript const entries = await client.getEntries({ content_type: "blog_post" }) ``` > **Info** > > 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](/concepts/links#link-field-for-entry). 2. 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: ```javascript const localizedEntries = await client.withAllLocales.getEntries({ content_type: "blog_post" }) ``` * `withoutLinkResolution`—Use this modifier to disable the automatic resolution of linked entries: ```javascript 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: ```javascript const entriesWithoutUnresolvable = await client.withoutUnresolvableLinks.getEntries({ content_type: "blog_post" }) ``` > **Info** > > To use the same configuration throughout your project, you can define the chain in the beginning and use it as such: `javascript const baseClient = contentful.createClient({ accessToken: "", space: "", }) 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](https://github.com/contentful/contentful.js/blob/master/TYPESCRIPT.md#response-types) 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](https://github.com/contentful/contentful.js/blob/master/MIGRATION.md#migration-to-contentfuljs-10x). ## 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](https://docs.google.com/forms/d/e/1FAIpQLSdvtNov3Bs3csuvizgKbR9uP3pYN7b3ElXIUz0pl-MCQh1qZw/viewform). ## Next steps * [Get started with the JavaScript client library](/sdks/javascript/tutorials/using-js-cda-sdk/) * [Explore the TypeScript reference on GitHub](https://github.com/contentful/contentful.js/blob/master/TYPESCRIPT.md) * [Migrate to contentful.js version 10](https://github.com/contentful/contentful.js/blob/master/MIGRATION.md) > This tutorial explains some examples of using JavaScript with TypeScript | query types | chained client modifiers.