{"id":17776393,"url":"https://github.com/kontent-ai/react-components","last_synced_at":"2025-06-26T06:35:18.760Z","repository":{"id":38836742,"uuid":"459635559","full_name":"kontent-ai/react-components","owner":"kontent-ai","description":"Package containing React components useful when processing Kontent.ai's data to the site.","archived":false,"fork":false,"pushed_at":"2024-04-29T10:34:58.000Z","size":1670,"stargazers_count":4,"open_issues_count":1,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-04-29T11:42:14.160Z","etag":null,"topics":["components","hacktoberfest","javascript","kontent","kontent-ai","kontent-ai-tool","react","typescript"],"latest_commit_sha":null,"homepage":"https://kontent.ai","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kontent-ai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-02-15T15:24:32.000Z","updated_at":"2024-06-27T07:45:02.564Z","dependencies_parsed_at":"2024-04-29T11:54:22.117Z","dependency_job_id":null,"html_url":"https://github.com/kontent-ai/react-components","commit_stats":{"total_commits":66,"total_committers":11,"mean_commits":6.0,"dds":0.4545454545454546,"last_synced_commit":"2cf467dcfb307cfb4615c0209bdede6c3962b22e"},"previous_names":["simply007/kontent-react-components"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/kontent-ai/react-components","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kontent-ai%2Freact-components","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kontent-ai%2Freact-components/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kontent-ai%2Freact-components/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kontent-ai%2Freact-components/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kontent-ai","download_url":"https://codeload.github.com/kontent-ai/react-components/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kontent-ai%2Freact-components/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262016321,"owners_count":23245499,"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":["components","hacktoberfest","javascript","kontent","kontent-ai","kontent-ai-tool","react","typescript"],"created_at":"2024-10-26T22:05:30.791Z","updated_at":"2025-06-26T06:35:18.734Z","avatar_url":"https://github.com/kontent-ai.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kontent.ai's React Components\n\n\u003e[!WARNING]\n\u003e**Deprecation notice**\n\u003e\n\u003eThis repository has been archived and is no longer maintained. Module superseded by [@kontent-ai/rich-text-resolver](https://github.com/kontent-ai/rich-text-resolver-js).\n\nThe package containing React components useful when processing Kontent.ai's data to the site.\n\n## Install\n\n```sh\nnpm install @kontent-ai/react-components\n```\n\n### Typescript\n\nComponents exports their typescript definitions so that you know what data format you need to provide via props and what data format expect from function prop callback arguments.\n\n## Rich text element component\n\nRich text elements from Kontent.ai could be resolved to React components using [html-react-parser](https://www.npmjs.com/package/html-react-parser) (based on [this article](https://rshackleton.co.uk/articles/rendering-kentico-cloud-linked-content-items-with-react-components-in-gatsby))\n\nThis package should make the usage easier. Basically by loading the rich text data and use these components to provide this data and resolver functions.\n\n\u003e More showcases could be found in [RichTextElement.spec.tsx](./tests/components/rich-text-element/RichTextElement.spec.tsx).\n\n```tsx\nimport { createDeliveryClient, Elements } from '@kontent-ai/delivery-sdk';\nimport { isComponent, isLinkedItem, RichTextElement } from '@kontent-ai/react-components';\nimport { Element as DomHandlerElement } from 'domhandler';\n\n// ...\n\nconst client =  createDeliveryClient({\n    environmentId: '\u003cYOUR ENVIRONMENT ID\u003e'\n});\n\nconst response = await client.item(\"\u003cYOUR ITEM CODENAME\u003e\"))\n    .toPromise();\n\n// ...\n\n\u003cRichTextElement\n    richTextElement={response.item.elements[\"bio\"] as Elements.RichTextElement}\n    resolvers={{\n        resolveLinkedItem: (linkedItem, { domElement, domToReact }) =\u003e {\n            if (isComponent(domElement)) {\n                return (\n                    \u003c\u003e\n                        \u003ch1\u003eComponent\u003c/h1\u003e\n                        \u003cpre\u003e{JSON.stringify(linkedItem, undefined, 2)}\u003c/pre\u003e;\n                    \u003c/\u003e\n                );\n            }\n            if (isLinkedItem(domElement)) {\n                return (\n                    \u003c\u003e\n                        \u003ch1\u003eLinked item\u003c/h1\u003e\n                        \u003cpre\u003e{JSON.stringify(linkedItem, undefined, 2)}\u003c/pre\u003e;\n                    \u003c/\u003e\n                );\n            }\n            throw new Error(\"Unknown type of the linked item's dom node\");\n        },\n        resolveImage: (image, { domElement, domToReact }): JSX.Element =\u003e (\n            \u003cimg\n                src={image.url}\n                alt={image.description ? image.description : image.imageId}\n                width=\"200\"\n            /\u003e\n        ),\n        resolveLink: (link, { domElement, domToReact }): JSX.Element =\u003e (\n            \u003ca href={`/${link.type}/${link.urlSlug}`}\u003e\n                {domToReact(domElement.children)}\n            \u003c/a\u003e\n        ),\n        resolveDomNode: ({ domNode, domToReact }) =\u003e {\n            if (domNode instanceof DomHandlerElement \u0026\u0026 domNode.name === 'table') {\n                return \u003cdiv className=\"table-wrapper\"\u003e{domToReact([domNode])}\u003c/div\u003e;\n            }\n        }\n    }}\n/\u003e\n```\n\n### Multilevel resolving\n\nIf you want to resolve multiple levels of components and linked items in rich text, it is possible to use the component recursively and reuse the resolving logic.\n\nThere is an example when rich text can have `row` components, and these can contains `column` components with html.\n\n```tsx\n// resolving functionality\nconst resolveLinkedItemsRecursively: ResolveLinkedItemType = (\n  linkedItem,\n  _domNode\n) =\u003e {\n  switch (linkedItem?.system.type) {\n    case \"row\":\n      return (\n        \u003cdiv className=\"row\"\u003e\n          \u003cRichTextElement\n            richTextElement={\n              linkedItem?.elements[\"columns\"] as Elements.RichTextElement\n            }\n            // Recursively resolve items in the rich text\n            resolvers={{\n              resolveLinkedItem: resolveLinkedItemsRecursively,\n            }}\n          /\u003e\n        \u003c/div\u003e\n      );\n    case \"column\":\n      return (\n        \u003cdiv className=\"column\"\u003e\n          \u003cRichTextElement\n            richTextElement={\n              linkedItem?.elements[\"content\"] as Elements.RichTextElement\n            }\n            resolvers={{\n              resolveLinkedItem: resolveLinkedItemsRecursively,\n            }}\n          /\u003e\n        \u003c/div\u003e\n      );\n  }\n};\n\n// SO the top level rich text would define\n\u003cRichTextElement\n  richTextElement={\n    multiLevelComponentsRichTextItem.item.elements[\n      \"content\"\n    ] as Elements.RichTextElement\n  }\n  resolvers={{\n    resolveLinkedItem: resolveLinkedItemsRecursively,\n  }}\n/\u003e;\n```\n\n\u003e ⚠ Recursive resolution could lead to infinite loops, if you have a circular dependency. To avoid that, you can store the codenames of already processed items and if you hit the same one during resolution, break the resolution chain - this could happen only if you use linked items, not components in rich text.\n\n### Return vs. Mutate DOM Node\n\nBy returning the react components in any of the resolvers functions, you stop traversing the DOM tree under the current DOM node (its children). If you just want to avoid that behavior, you can mutate the provided DOM node and return `undefined`.\n\nIn this showcase a simple html is being resolved and for `\u003cp\u003e` tags and all `\u003cstrong\u003e` tags a proper class is being set without stopping and traversing.\n\n```tsx\n\u003cRichTextElement\n  richTextElement={{\n    ...emptyRichText,\n    value: \"\u003cp\u003eLorem ipsum with \u003cstrong\u003ebold text\u003c/strong\u003e\u003c/p\u003e\",\n  }}\n  resolvers={{\n    resolveDomNode: ({ domNode, domToReact }) =\u003e {\n      if (domNode instanceof DomHandlerElement) {\n        if (domNode.name === \"strong\") {\n          domNode.attribs.class = domNode.attribs.class\n            ? domNode.attribs.class + \" strongClass\"\n            : \"strongClass\";\n          return undefined;\n        } else if (domNode.name === \"p\") {\n          domNode.attribs.class = domNode.attribs.class\n            ? domNode.attribs.class + \" pClass\"\n            : \"pClass\";\n          return undefined;\n        }\n      }\n    },\n  }}\n/\u003e\n```\n\nThe outcome is\n\n```html\n\u003cp className=\"pClass\"\u003e\n  Lorem ipsum with\n  \u003cstrong className=\"strongClass\"\u003e bold text \u003c/strong\u003e\n\u003c/p\u003e\n```\n\n## Feedback\n\nIf you have any feedback, feel free to submit an issue or open a PR!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkontent-ai%2Freact-components","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkontent-ai%2Freact-components","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkontent-ai%2Freact-components/lists"}