{"id":13876188,"url":"https://github.com/amplience/dc-delivery-sdk-js","last_synced_at":"2025-04-04T10:03:35.738Z","repository":{"id":34299235,"uuid":"174337404","full_name":"amplience/dc-delivery-sdk-js","owner":"amplience","description":"Official Javascript SDK for the Amplience Dynamic Content Delivery API","archived":false,"fork":false,"pushed_at":"2025-03-26T15:54:44.000Z","size":3422,"stargazers_count":55,"open_issues_count":33,"forks_count":10,"subscribers_count":18,"default_branch":"master","last_synced_at":"2025-03-28T09:05:18.308Z","etag":null,"topics":["content-management","headless-cms","javascript","sdk","typescript","web"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/amplience.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-07T12:10:30.000Z","updated_at":"2025-01-29T13:34:43.000Z","dependencies_parsed_at":"2024-08-29T10:58:46.883Z","dependency_job_id":"1a68fbd6-4929-447c-8dab-6a9bd5520d5a","html_url":"https://github.com/amplience/dc-delivery-sdk-js","commit_stats":{"total_commits":66,"total_committers":13,"mean_commits":5.076923076923077,"dds":0.7878787878787878,"last_synced_commit":"03819b4abd00d8a3e35fc31668f1f62ea591c325"},"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amplience%2Fdc-delivery-sdk-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amplience%2Fdc-delivery-sdk-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amplience%2Fdc-delivery-sdk-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/amplience%2Fdc-delivery-sdk-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/amplience","download_url":"https://codeload.github.com/amplience/dc-delivery-sdk-js/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247157045,"owners_count":20893202,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["content-management","headless-cms","javascript","sdk","typescript","web"],"created_at":"2024-08-06T06:01:06.886Z","updated_at":"2025-04-04T10:03:35.692Z","avatar_url":"https://github.com/amplience.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","web"],"sub_categories":[],"readme":"# dc-delivery-sdk-js\n\n\u003e Official Javascript SDK for the Amplience Dynamic Content Delivery API\n\n[![npm version](https://badge.fury.io/js/dc-delivery-sdk-js.svg)](https://badge.fury.io/js/dc-delivery-sdk-js)\n\nThis SDK is designed to help build client side and server side content managed applications.\n\n## Features\n\n- Fetch content and slots using [Content Delivery 1](https://docs.amplience.net/integration/deliveryapi.html#the-content-delivery-api) or [Content Delivery 2](https://docs.amplience.net/development/contentdelivery/readme.html)\n- Fetch fresh content and slots for use with SSG build tools using the [Fresh API](https://amplience.com/docs/development/freshapi/fresh-api.html)\n- Fetch preview content using Virtual Staging\n- Transform content using the [Content Rendering Service](https://docs.amplience.net/integration/contentrenderingservice.html#the-content-rendering-service)\n- Localize content\n- Transform images on the fly using the [Dynamic Media Service](http://playground.amplience.com/di/app/#/intro)\n- Filter Content Items using the [FilterBy](https://amplience.com/docs/development/contentdelivery/filterandsort.html) endpoint\n- Fetch Hierarchies using the Hierarchies endpoint in CDv2\n\nSo we can have nice things:\n\n- ES6 module \u0026 tree-shaking support for tools capable of using [ES6 imports](https://github.com/rollup/rollup/wiki/pkg.module) (like [Rollup](http://rollupjs.org/), [Webpack](https://webpack.js.org/), or [Parcel](https://parceljs.org/))\n- Backwards compatibility for Node.js-style (CommonJS) imports\n- TypeScript type definitions\n- Universal Module Definition (UMD) to support direct use in the browser\n\n## Installation\n\nUsing npm:\n\n```sh\nnpm install dc-delivery-sdk-js --save\n```\n\nUsing cdn:\n\n```html\n\u003cscript src=\"https://unpkg.com/dc-delivery-sdk-js/dist/dynamicContent.browser.umd.min.js\"\u003e\u003c/script\u003e\n```\n\nfor legacy browsers:\n\n```html\n\u003cscript src=\"https://unpkg.com/dc-delivery-sdk-js/dist/dynamicContent.browser.umd.legacy.min.js\"\u003e\u003c/script\u003e\n```\n\n## Usage\n\nThis SDK supports browser and Node.js applications using ES6 or CommonJS style imports.\n\nES6:\n\n```js\nimport { ContentClient } from 'dc-delivery-sdk-js';\n\nconst client = new ContentClient({\n  hubName: 'myhub',\n});\n```\n\nCommonJS:\n\n```js\nconst ContentClient = require('dc-delivery-sdk-js').ContentClient;\n\nconst client = new ContentClient({\n  hubName: 'myhub',\n});\n```\n\nIf your application does not use a package manager you can directly include the pre-bundled version of the SDK and access the features using the global \"ampDynamicContent\".\n\n```html\n\u003cscript src=\"https://unpkg.com/dc-delivery-sdk-js/dist/dynamicContent.browser.umd.min.js\"\u003e\u003c/script\u003e\n```\n\n```js\nconst client = new ampDynamicContent.ContentClient({\n  hubName: 'myhub',\n});\n```\n\nIf you need to support old browsers a legacy version of the bundle is provided, however we strongly recommend using a tool like [babel](https://babeljs.io/) in your project to compile the SDK to your exact browser requirements.\n\n### Configuration options\n\n| Option             | Description                                                                                                                                                                 |\n| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| account            | Content Delivery 1 API - Required\\* - Account to retrieve content from                                                                                                      |\n| hubName            | Content Delivery 2 API - Required\\* - hubName to retrieve content from - [finding the hub name](https://docs.amplience.net/development/contentdelivery/readme.html#hubname) |\n| apiKey             | Fresh API - Required\\* - API key required for use with the Fresh API service. `hubName` must also be set                                                                    |\n| retryConfig        | Allows override of the default [retry configuration](#override-fresh-api-retry-configuration) used by the Fresh API client                                                  |\n| stagingEnvironment | If set, the SDK will request content and media from the staging environment host name specified.                                                                            |\n| locale             | If set, the SDK will request content using the locale settings provided.                                                                                                    |\n| mediaHost          | Allows users with custom hostnames to override the hostname used when constructing media URLs.                                                                              |\n| secureMediaHost    | Allows users with custom hostnames to override the hostname used when constructing secure media URLs.                                                                       |\n| baseUrl            | Override for the content delivery API base URL                                                                                                                              |\n| adaptor            | Allows custom handling of requests which makes testing and supporting non-standard environments easier.                                                                     |\n| timeout            | If set, requests made will timeout after the number of milliseconds specified.                                                                                              |\n\n\\* see [Content Delivery versions](#content-delivery-versions)\n\n### Content Delivery versions\n\nIn order to use the client, it must be configured with either `account` or `hubName`. If `apiKey` is set a Fresh API client will be created.\n\nIf **account** \u0026 **hubName** are supplied, the SDK will only use the **Content Delivery 2 API**.\nIf **hubName** and **apiKey** are supplied, the SDK will only use the **Fresh API**.\n\nTo create a Fresh API client both `hubName` and `apiToken` must be specified\n\n### Fetch content by delivery ID\n\nOnce your client is created you can request content for a slot or content item id. This will return a promise which will resolve to the JSON of your slot or content item. If no content is found with the provided id the promise will reject with an error.\n\n```js\nconst slotId = 'cb671f37-0a66-46c3-a011-54ce3cdff241';\nclient\n  .getContentItemById(slotId)\n  .then((content) =\u003e {\n    console.log(content.body);\n  })\n  .catch((error) =\u003e {\n    console.log('content not found', error);\n  });\n```\n\nThe format of the content object will be specific to your content types, which define the JSON structure of content items and slots, however a set of standard metadata is always included in a property called \"\\_meta\".\n\nIf the slot or content item requested returns a graph of content, for example a carousel may also return linked slides, these will be included inline in the JSON.\n\nExample:\n\n```json\n{\n  \"_meta\": {\n    \"schema\": \"https://www.anyafinn.online/content-types/carousel.json\",\n    \"deliveryId\": \"543246b7-5948-4849-884c-b295402a95b4\",\n    \"name\": \"example-carousel\"\n  },\n  \"slides\": [\n    {\n      \"_meta\": {\n        \"schema\": \"https://www.anyafinn.online/content-types/slide.json\",\n        \"deliveryId\": \"d6ccc158-6ab7-48d0-aa85-d9fbf2aef000\",\n        \"name\": \"example-slide\"\n      },\n      \"heading\": \"Free shipping until Sunday!\"\n    }\n  ]\n}\n```\n\n### Fetch content by delivery key _(Content Delivery 2 and Fresh API only)_\n\n**Note:** Fetching content by delivery key via `getContentItemByKey()` is only supported when using [Content Delivery 2 or Fresh API](#content-delivery-versions)\n\nOnce you have [set a delivery key for a slot or content item](https://docs.amplience.net/development/delivery-keys/readme.html), the content item must be published before it can be retrieved using this SDK.\n\nThe `getContentItemByKey()` method will return a promise which will resolve to the JSON of your slot or content item. If no content is found with the provided key the promise will reject with an error.\n\n```js\nconst client = new ContentClient({\n  hubName: 'myhub',\n});\n\nconst slot = 'homepage-banner-slot';\nclient\n  .getContentItemByKey(slot)\n  .then((content) =\u003e {\n    console.log(content.body);\n  })\n  .catch((error) =\u003e {\n    console.log('content not found', error);\n  });\n```\n\nThe format of the content object will be specific to your content types, which define the JSON structure of content items and slots, however a set of standard metadata is always included in a property called \"\\_meta\" along with the `deliveryKey` on content items that have it defined.\n\nIf the slot or content item requested returns a graph of content, for example a carousel may also return linked slides, these will be included inline in the JSON.\n\nThe delivery key\n\nExample:\n\n```json\n{\n  \"_meta\": {\n    \"schema\": \"https://www.anyafinn.online/content-types/carousel.json\",\n    \"deliveryId\": \"543246b7-5948-4849-884c-b295402a95b4\",\n    \"deliveryKey\": \"homepage-banner-slot\",\n    \"name\": \"example-carousel\"\n  },\n  \"slides\": [\n    {\n      \"_meta\": {\n        \"schema\": \"https://www.anyafinn.online/content-types/slide.json\",\n        \"deliveryId\": \"d6ccc158-6ab7-48d0-aa85-d9fbf2aef000\",\n        \"name\": \"example-slide\"\n      },\n      \"heading\": \"Free shipping until Sunday!\"\n    }\n  ]\n}\n```\n\n### Filtering Content Items\n\n**Note:** Filtering content via `filterBy() | filterByContentType() | filterByParentId() | filterContentItems()` is only supported when using [Content Delivery 2 or Fresh API](#content-delivery-versions).\n\nFiltering by Content Type or Parent ID is enabled by default. You can also filter by any other field in your schema once [you enable it](https://amplience.com/docs/development/contentdelivery/filterandsort.html).\n\n#### Constructing a request\n\nThe `filterBy() | filterByContentType() | filterByParentId()` method will return a instance of the `FilterBy` class which has helper functions to construct a filterBy request.\n\n`filterByContentType() | filterByParentId()` are helper methods.\n\n```ts\nclient.filterByContentType('https://bigcontent.io/blog.json');\n// is equivalent to this:\nclient.filterBy('/_meta/schema', 'https://bigcontent.io/blog.json');\n\nclient.filterByParentId('c6d9e038-591b-4ca2-874b-da354f5d6e61');\n// is equivalent to this:\nclient.filterBy(\n  '/_meta/hierarchy/parentId',\n  'c6d9e038-591b-4ca2-874b-da354f5d6e61'\n);\n```\n\nCalling `request` executes the request returning a `Promise` if no content is found an empty response object will be returned. If invalid options are provided it will reject with an error.\n\n```ts\nconst client = new ContentClient({\n  hubName: 'myhub',\n});\n\nconst res = await client\n  .filterByContentType('https://example.com/blog-post-filter-and-sort')\n  .filterBy('/category', 'Homewares')\n  .sortBy('readTime', 'DESC')\n  .page(2)\n  .request({\n    format: 'inlined',\n    depth: 'all',\n  });\n\nconsole.log(res);\n```\n\nThe response from `filterBy() | filterByContentType() | filterByParentId() | filterContentItems()` will match the API response but with an added helper function if the next page is available under `page.next()`.\n\n```js\n{\n  responses: [\n    {\n      content: {\n        _meta: {\n          name: 'Homewares blog post',\n          schema: 'https://example.com/blog-post-filter-and-sort',\n          deliveryKey: 'new/homeware-collection/about',\n          deliveryId: '1024dc7a-f255-46a7-b374-be85081a562f',\n        },\n        title: 'All about our new homeware collection',\n        category: 'Homewares',\n        date: '2021-05-05',\n        ranking: 4,\n        description:\n          'Our new homeware has just landed. Find out how you can fill your home with some exciting designs.',\n        readTime: 5,\n      },\n    },\n    {\n      content: {\n        _meta: {\n          name: 'Summer collection blog',\n          schema: 'https://example.com/blog-post-filter-and-sort',\n          deliveryKey: 'new/summer-fashion/about',\n          deliveryId: 'fb466729-b604-496f-be36-521013a752d2',\n        },\n        title: 'Our new summer collection blog',\n        category: 'Homewares',\n        date: '2021-05-05',\n        ranking: 2,\n        description: 'A sneak peak at our new summer collection',\n        readTime: 4,\n      },\n    },\n  ],\n  page: {\n    responseCount: 2,\n    next: () =\u003e // next page\n    nextCursor:\n      'eyJzb3J0S2V5IjoiXCIgNUAmJTYwOTJiZjBhNGNlZGZkMDAwMWVhZTY3ZCIsIml0ZW1JZCI6ImFtcHByb2R1Y3QtZG9jOjg2Y2E2YjgxLTJkOGYtNDRiMi1iNGQ1LTFlZjU0MzgzMzMyMyJ9',\n  },\n}\n```\n\n#### Alternative constructing a filterBy request\n\nWe also provide a way of requesting by a request object which is identical to the the request above\n\n```ts\nconst client = new ContentClient({\n  hubName: 'myhub',\n});\n\nconst res = await client.filterContentItems({\n  filterBy: [\n    {\n      path: '/_meta/schema',\n      value: 'https://example.com/blog-post-filter-and-sort',\n    },\n    {\n      path: '/category',\n      value: 'Homewares',\n    },\n  ],\n  sortBy: {\n    key: 'readTime',\n    order: 'DESC',\n  },\n  page: {\n    size: 2,\n  },\n  parameters: {\n    format: 'inlined',\n    depth: 'all',\n  },\n});\n\nconsole.log(res);\n```\n\n### Fetching hierarchies in a single request\n**Note:** Fetching content via `getByHierarchy()` is only supported when using [Content Delivery 2 or Fresh API](#content-delivery-versions).\nThis method wraps the Hierarchies endpoint of CDv2 and allows the fetching of hierarchical content from it's root node.\n```ts\nclient.getByHierarchy({rootId: '90d6fa96-6ce0-4332-b995-4e6c50b1e233'})\n```\nThe response from the delivery service is then reconstructed from the flat data structure of the response into a content tree\n```json\n{\n  \"content\": {\n    \"_meta\": {\n      \"name\": \"Root\",\n      \"schema\": \"https://hierarchies.com\",\n      \"hierarchy\": {\n        \"root\": true\n      },\n      \"deliveryId\": \"90d6fa96-6ce0-4332-b995-4e6c50b1e233\"\n    },\n    \"propertyName1\": \"Root\"\n  },\n  \"children\": [\n    {\n      \"content\": {\n        \"_meta\": {\n          \"name\": \"A\",\n          \"schema\": \"https://hierarchies.com\",\n          \"hierarchy\": {\n            \"parentId\": \"90d6fa96-6ce0-4332-b995-4e6c50b1e233\",\n            \"root\": false\n          },\n          \"deliveryId\": \"1ebab07d-acd8-4e19-a614-ec632cdf95d5\"\n        },\n        \"propertyName1\": \"A\"\n      },\n      \"children\": [\n        {\n          \"content\": {\n            \"_meta\": {\n              \"name\": \"B\",\n              \"schema\": \"https://hierarchies.com\",\n              \"hierarchy\": {\n                \"parentId\": \"1ebab07d-acd8-4e19-a614-ec632cdf95d5\",\n                \"root\": false\n              },\n              \"deliveryId\": \"4db37251-0c86-4f45-ad8a-583ebf6efc80\"\n            },\n            \"propertyName1\": \"B\"\n          },\n          \"children\": []\n        },\n        {\n          \"content\": {\n            \"_meta\": {\n              \"name\": \"C\",\n              \"schema\": \"https://hierarchies.com\",\n              \"hierarchy\": {\n                \"parentId\": \"1ebab07d-acd8-4e19-a614-ec632cdf95d5\",\n                \"root\": false\n              },\n              \"deliveryId\": \"68676cda-5ab2-4a5e-bcfb-58c5cf3eb8ed\"\n            },\n            \"propertyName1\": \"C\"\n          },\n          \"children\": []\n        }\n      ]\n    }\n  ]\n}\n```\n### Fetching multiple Content Items or Slots in a single request\n\n**Note:** Fetching content via `getContentItemsById() | getContentItemsByKey() | getContentItems() | fetchContentItems()` is only supported when using [Content Delivery 2 or Fresh API](#content-delivery-versions).\n\nWraps [`/content/fetch`](https://amplience.com/docs/api/dynamic-content/delivery/content-delivery-2/index.html#operation/multiGetContent) endpoint. [Additional documentation](https://amplience.com/docs/development/contentdelivery/readme.html#multipleitems).\n\n#### Get content items by delivery ID\n\nFetch multiple by delivery id e.g.,\n\n```ts\nclient.getContentItemsById([\n  'd6ccc158-6ab7-48d0-aa85-d9fbf2aef000',\n  'b322f84a-9719-42ff-a6a0-6e2924608d19',\n]);\n```\n\n#### Get content items by key\n\nFetch multiple by delivery key e.g.,\n\n```ts\nclient.getContentItemsByKey(['blog/article-1', 'blog/article-2']);\n```\n\n#### Get content items\n\nLess verbose version of `fetchContentItems` allowing fetching of content by both delivery keys and ids as well as per request parameters and global parameter overrides\n\n```ts\nclient.getContentItems([{\n  key: 'blog/article-1', overrides: {locale: 'en-US'}\n  key: 'blog/article-2'\n}], {locale: 'en'});\n```\n\n#### Fetch content items\n\nAllows full construction of the request body.\n\n```ts\nclient.fetchContentItems({\n  requests: [{\n    key: 'blog/article-1', overrides: {locale: 'en'}\n    key: 'blog/article-2'\n  }],\n  parameters: {depth: 'root'}\n});\n```\n\n### Preview staging content\n\nBy default, the content client will request content from the production content delivery services. When a user wants to preview content before it is published you can re-point the client to a virtual staging environment (VSE):\n\n```js\nconst client = new ContentClient({\n  account: 'myaccount',\n  stagingEnvironment: 'fhboh562c3tx1844c2ycknz96.staging.bigcontent.io',\n});\n```\n\nDynamic Content generates a VSE for each user and typically passes the \"stagingEnvironment\" value into your application using a URL parameter. This allows each user to effectively have their own staging environment which allows content producers to work in parallel.\n\n#### Previewing staging content for a given Snapshot or at a given point in time (time machine)\n\nYou can use the `StagingEnvironmentFactory` to generate a new staging environment that is 'pinned' to a Snapshot or a timestamp, which then can be passed into the ContentClient.\n\nPreviewing content for a given Snapshot:\n\n```js\nconst factory = new StagingEnvironmentFactory(\n  'fhboh562c3tx1844c2ycknz96.staging.bigcontent.io'\n);\nconst stagingEnvironmentAtSnapshot = await factory.generateDomain({\n  snapshotId: 'abcdef123456',\n});\n\nconst client = new ContentClient({\n  account: 'myaccount',\n  stagingEnvironment: stagingEnvironmentAtSnapshot,\n});\n```\n\nPreviewing content at a given timestamp (epoch milliseconds):\n\n```js\nconst factory = new StagingEnvironmentFactory(\n  'fhboh562c3tx1844c2ycknz96.staging.bigcontent.io'\n);\nconst stagingEnvironmentAtTimestamp = await factory.generateDomain({\n  timestamp: 1546264721816,\n});\n\nconst client = new ContentClient({\n  account: 'myaccount',\n  stagingEnvironment: stagingEnvironmentAtTimestamp,\n});\n```\n\n### Localize content\n\nContent types can make use of [field-level localization](https://docs.amplience.net/production/localization.html#field-level-localization) to give content producers the ability to enter locale specific values for a field.\n\nBy default, every locale value will be returned in the content object:\n\n```json\n{\n  \"_meta\": {\n    \"schema\": \"https://www.anyafinn.online/content-types/slide.json\",\n    \"deliveryId\": \"d6ccc158-6ab7-48d0-aa85-d9fbf2aef000\",\n    \"name\": \"example-slide\"\n  },\n  \"heading\": {\n    \"_meta\": {\n      \"schema\": \"http://bigcontent.io/cms/schema/v1/core#/definitions/localized-value\"\n    },\n    \"values\": [\n      {\n        \"locale\": \"en-US\",\n        \"value\": \"Free shipping until Sunday!\"\n      },\n      {\n        \"locale\": \"de-de\",\n        \"value\": \"Kostenloser Versand bis Sonntag!\"\n      }\n    ]\n  }\n}\n```\n\nIf desired, you can configure the SDK with a locale query. If set, the locale matching is performed server side and only a single value will be returned.\n\n```js\nconst client = new ContentClient({\n  account: 'myaccount',\n  locale: 'en-US,en-*',\n});\n```\n\nReturns\n\n```json\n{\n  \"_meta\": {\n    \"schema\": \"https://www.anyafinn.online/content-types/slide.json\",\n    \"deliveryId\": \"d6ccc158-6ab7-48d0-aa85-d9fbf2aef000\",\n    \"name\": \"example-slide\"\n  },\n  \"heading\": \"Free shipping until Sunday!\"\n}\n```\n\n### Transform images\n\nIn addition to serving image and Video content, Dynamic Content can also transform media on the fly allowing you to target multiple channels and deliver just the pixels required from a single master asset.\n\nThe SDK attaches helper functions to Image and Video properties to simplify constructing Dynamic Media URLs:\n\n```js\nconst ImageFormat = require('dc-delivery-sdk-js').ImageFormat;\n\nconst imageUrl = content.body.imageProperty\n  .url()\n  .width(500)\n  .height(500)\n  .sharpen()\n  .format(ImageFormat.WEBP)\n  .build();\n```\n\nSee the SDK [reference documentation](https://amplience.github.io/dc-delivery-sdk-js/) for further details.\n\n### Transform content\n\nUsing the [Content Rendering Service](https://docs.amplience.net/integration/contentrenderingservice.html#the-content-rendering-service), you can convert the JSON content into any format you choose by applying a template previously setup in the back-office. This is typically used to convert content into fragments of HTML, XML or even rewrite the JSON.\n\n```js\nclient\n  .renderContentItem('b322f84a-9719-42ff-a6a0-6e2924608d19', 'templateName')\n  .then((response) =\u003e {\n    console.log(response.body);\n  })\n  .catch((error) =\u003e {\n    console.log('unable to find content', error);\n  });\n```\n\n## Advanced\n\n### Override Fresh API retry configuration\n\nBy default, if a 429 status code is received the SDK will retry up to 3 more times using exponential backoff. The configuration options below may be overridden.\n\n| Name           | Type       | Default            | Description                                                                                                                                                                                                                                                                                              |\n| -------------- | ---------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| retries        | `Number`   | `3`                | The number of times to retry before failing.                                                                                                                                                                                                                                                             |\n| retryDelay     | `Function` | `exponentialDelay` | A callback to further control the delay in milliseconds between retried requests. By default there is an exponential delay between retries ([Exponential Backoff](https://developers.google.com/analytics/devguides/reporting/core/v3/errors#backoff)). The function is passed `retryCount` and `error`. |\n| retryCondition | `Function` | `isThrottled`      | A callback to further control if a request should be retried. By default, it retries if the response status is 429.                                                                                                                                                                                      |\n\n### Detecting content types\n\nWhen displaying content you may need to detect the content type to decide which UI widget should be used to display the content.\n\nEvery content item in the body includes a built-in property \\_meta.schema which identifies the content type that was used to create that fragment of content. This can be used by your application to influence how the content is processed.\n\nExample:\n\n```json\n{\n  \"_meta\": {\n    \"schema\": \"https://www.anyafinn.online/content-types/slot.json\",\n    \"deliveryId\": \"62ece7d6-b541-411c-b776-0a6704ede1fb\",\n    \"name\": \"homepage-hero\"\n  },\n  \"slotContent\": {\n    \"_meta\": {\n      \"schema\": \"https://www.anyafinn.online/content-types/banner.json\",\n      \"deliveryId\": \"28583572-c964-4755-825b-044718312a29\",\n      \"name\": \"example-banner\"\n    },\n    \"heading\": \"Free shipping until Sunday!\"\n  }\n}\n```\n\n```js\nimport React from 'react';\nimport { Banner, Carousel, Empty } from './components';\n\nclass App extends React.Component {\n  //...\n\n  getComponentForContentType(contentItem) {\n    switch (contentItem._meta.schema) {\n      case 'https://www.anyafinn.online/content-types/banner.json':\n        return Banner;\n      case 'https://www.anyafinn.online/content-types/carousel.json':\n        return Carousel;\n      default:\n        return Empty;\n    }\n  }\n\n  render() {\n    const slotContent = this.props.content.slotContent;\n    const TagName = this.getComponentForContentType(slotContent);\n    return \u003cTagName content={slotContent} /\u003e;\n  }\n}\n```\n\n### Strongly typed content\n\nApplications that support TypeScript can optionally create interfaces to represent content types within the code. This can be passed as a generic parameter when loading content which will result in a typed content body.\n\n```typescript\ninterface Banner extends ContentBody {\n  heading: string;\n}\n\nclient.getContentItem\u003cBanner\u003e('ec5d12cc-b1bb-4df4-a7b3-fd7796326cfe');\n```\n\n```ts\ninterface BlogPost {\n  title: string;\n  category: string;\n  date: string;\n  ranking: number;\n  description: string;\n  readTime: number;\n}\n\nconst res = await client\n  .filterByContentType\u003cBlogPost\u003e(\n    'https://example.com/blog-post-filter-and-sort'\n  )\n  .request();\n\nconsole.log(res);\n```\n\n### Custom media CNAMEs\n\nIf you have previously configured custom CNAMEs for your media hosting, you can override the hostname used by the SDK when constructing image URLs as shown below:\n\n```js\nconst client = new ContentClient({\n  account: 'myaccount',\n  mediaHost: 'images.mybrand.com',\n  secureMediaHost: 'images.mybrand.com',\n});\n```\n\n## Documentation\n\nPlease use the following documentation resources to assist building your application:\n\n- Dynamic Content SDK [Reference documentation](https://amplience.github.io/dc-delivery-sdk-js/)\n- Dynamic Content Delivery API [Reference documentation](https://docs.amplience.net/integration/deliveryapi.html#the-content-delivery-api)\n- Dynamic Content Delivery API 2 [Reference documentation](https://amplience.com/docs/development/contentdelivery/readme.html)\n- Dynamic Content Fresh API [Reference documentation](https://amplience.com/docs/development/contentdelivery/filterapiintro.html)\n- Dynamic Content [User guide](https://docs.amplience.net/)\n\n## Getting Help\n\nIf you need help using the SDK please reach out using one of the following channels:\n\n- Ask a question on [StackOverflow](https://stackoverflow.com/) using the tag `amplience-dynamic-content`\n- Open a support ticket with [Amplience Support](https://support.amplience.com/)\n- Contact your [Amplience Customer Success](https://amplience.com/customer-success) representative\n- If you have found a bug please report it by [opening an issue](https://github.com/amplience/dc-delivery-sdk-js/issues/new)\n\n## License\n\nThis software is licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0),\n\nCopyright 2019-2021 Amplience\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\n..","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famplience%2Fdc-delivery-sdk-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Famplience%2Fdc-delivery-sdk-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Famplience%2Fdc-delivery-sdk-js/lists"}