{"_id":"bloomreach-experience-react-sdk","_rev":"115-401a7b3fe73df1e82bc191b2a9ee2a05","name":"bloomreach-experience-react-sdk","dist-tags":{"beta":"0.4.5-rc4","latest":"0.6.4"},"versions":{"0.1.0-rc1":{"name":"bloomreach-experience-react-sdk","version":"0.1.0-rc1","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.1.0-rc1","maintainers":[{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"ce7af8f7aafe4ee4943e0a6974c3f191f63b014f","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.1.0-rc1.tgz","fileCount":33,"integrity":"sha512-whrAlnYUu8sZVVtY3WCTtheu47iASgbc7b2RU3Y/JeRJBNlPJVD1b4Z6uxrh753n2SKbM8O2m106+tAQMqBnWg==","signatures":[{"sig":"MEUCIBQmDv7RUxF1Yq4IkNk4G7yFxgug9tpJg6JGC5rzJEwQAiEAws9vEa/sVxgUrOgIAXUqd+Cjfr5tTYNylmqCrwMkabM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":248424,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbWL+SCRA9TVsSAnZWagAA+YEP/jkp1flkm6JIGMCpRoBq\nYdYKXsELFIKZ6vPl2xWTD0EpGcrgS5ujXM7FAteTYxVhn5RJlzcRESilHlrL\nBj6eFn8R8HFLUA2kWaubQUROz2LFv+S/kOiO2NeNcvGoc+sZ6uNdTD1DxTSp\njjUkcJvSb3Oo/S+7MgoBzg97N9VYJtEfPcm3b9+FWMnbZkVBlvG1HaosVXLa\noXN1/iynwgbxZDqOsXICFNefH5eSPwo6TLGdZJQsaBEocbXyc5Er+CTdX4uo\n77HJdWzQIUSAGo7tq5llS3nhxZj+Qzc/bEmbCN8uIlfDsvlwKsopil0e+xkg\nWGYW0VRCx2NOc2QF6oTgPTYt432zUXhmzO4QWm12i+i5kh6b8kXqFXw7zbiT\n+8AjDytEQuZhzNjal1UseOUQ7IGMH/Q0JQtPEsNmmaQ168THEAVeF8zSHV/N\n9Bi55O2XUmsmL/BnnenbVqO6vRcbDVGe2xDlDCksH0jDns3p573T41HzQDHb\nrCB7rHvNg0ymjhkScRInUqqCSf1i8TeX/chnqy4M2TQbeR6KVJdDJiC6mFb5\n4jegctHijfkSy6LVJJDwYDzPcdsKecAws/ZMueVG2n0Kt2Of0IRssHoxL7+Q\nNexhVacRMw1xwx/92yo6bwuKT28On7mRxilYmrveeLRdwu1R/hIQQxDo+r29\nEMrX\r\n=5z0B\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","gitHead":"8d2df07ed03c35e8e5c2d0550828858d08099005","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"rkauffman","email":"robbertkauffman@gmail.com"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.1.0","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.6.0","dependencies":{"jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.1.0-rc1_1532542866103_0.6983881257666098","host":"s3://npm-registry-packages"}},"0.1.0":{"name":"bloomreach-experience-react-sdk","version":"0.1.0","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.1.0","maintainers":[{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"660bbc6aa2b27cd74d153303627c770a8ff58755","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.1.0.tgz","fileCount":33,"integrity":"sha512-WMq2iAEqlkxUi+3/tvJXc3G+rRvfiMOj+LLDq7N45VUUF0FQ3pVkK4XTFRMN34JOHUB95RyV07MI15zh0zWmCw==","signatures":[{"sig":"MEUCIB/PjTgxBG6f59XlMFcpNujrswQcXR0wIk2KLnnyYPeYAiEA53cL9oq+oQYhxTDXu/MvZw5zPK3IA0KpvP/3FLe+BOY=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":252821,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbWMS5CRA9TVsSAnZWagAAqdcP+QHyjS8GrHnMc00QDM2G\nMclhcCWxDv5I3OmZyyf+g02lhHmTv7wMR+da7E5gjdZKxE8/DKC5qI4mptmu\nNCJ7wWnXpvlb/CkXLVfVMnouTK9iUO85YhsvuB/sgqexjjCIkx1K2o4HhKe2\nFHrqvd+eOvdOQBvyzKnVDbVujE2mXKUUf+6CAlksJeI0V0Wd8LkiwWFXPaw0\nIV0CkEQprItYldYjY5R3XpWm//RKmzlYeiDyVAoxkOkYci2lx1MQusLmyNfi\nuLMAJrBYtrD4vx9wvyo2zpWdXfBFiNX2e7hzs9U0MV0NMK6/D5JguPNr8Shq\nenfIBGhnx73Ysu6FJ6Fw0FBFCM6KV4vTT6JzNyUmUeV3ycga5LR9l2nvk52C\nOHGeLEsa4LQZdw+cEGgGqnvLBy5cc9FMASgD9YzJdyheWXqgGViQYnd1eNNd\nTcp1mu+1dFJ6bxmZaCwD+lMYYd+Q63gGHZ+StgAYd7BcZy74mb1YGxIDbPTL\n8CMZzkVtV+aqPdRf2yfFNC4//HS/jbhdr+gAEIJ0Kp9xMNgnjDVDExm5L523\nTBFiZzAba4PNNMpwr0v1FA4EnLON4jZ050zphNPZjWH/j0ohpLTNQDU/u+Ut\nPL+EwKaTBg8dPYUtra9Q1O+lL/SmEXcieO0NoGaXWrKo3Q6poAkD3iedDP5i\nmsL/\r\n=Jkl5\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","gitHead":"78bf7102d66478937e72e515073ed90adf5d4ffa","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"rkauffman","email":"robbertkauffman@gmail.com"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.1.0","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.6.0","dependencies":{"jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.1.0_1532544185212_0.6063073501866605","host":"s3://npm-registry-packages"}},"0.1.1-rc1":{"name":"bloomreach-experience-react-sdk","version":"0.1.1-rc1","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.1.1-rc1","maintainers":[{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"c2ddd60334090447565330f8ee62628426346614","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.1.1-rc1.tgz","fileCount":28,"integrity":"sha512-Ul0uTqMOuidlVAOAKE86qXICY1BODcqg+KlFH2aZHV+PGLrnO4Wuv0s6xldPjhOAEUo32gPpxeyrt4J9X6UAmw==","signatures":[{"sig":"MEYCIQDYdXDG0hetNg/yewF84mYcfQMedJrqgaUn4oQGeWs5pAIhANMT9FXnwY36ogCh4bNtEwPOKk7K3O0UzeYHcZKqfao7","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":233581,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbWNDdCRA9TVsSAnZWagAAOOsP/0dE90MgfwMXkRjY7Ikq\nMuJ9drJn32LRHx1GarmME5lTPjRMlPEQJELxfQ/mWc5AgtM12b1VvUgIWq/F\noegzzSHGjfumBWVCQvh6McVzoz9aWJM/V/u0xFVr8XjEbifPXq+gilWrUkO5\nGc/VzdMH2hXITpzZnw4jdDbmxy3T+22MH6TukwSlbPRlx21lHBGHoIIitAcx\nfSsRRpm2efUKRvIuzk8+YSqLrEJP4S8OQaOgGD/y9GLzdqkhE6We6F/OziHU\nfVUwxGDymcRxuQkeufBB8ZOPa+wIAhpnOEjg39ohcI3jniwQnsUKvmhKGD7b\nEk3NOEhlJkutoFRc66acKflK8va4Tr9VZ9hvaPAM2QxZYFTRwKFgiLET/EcP\n0VHrewZ493JIQ+mb1PmtZ3p9aYEjRiZTaCH44GzHozVduYCIQ688GDPqUuNb\n7iGcJZfX8IOMEhejQqGNudSQcM38cII/3dys4QU3V8nE+ICUlJrFMYydyJsN\nSI2hRRl+a3qR3d5UHmxrDLyI1xID247ZG6BIdEjsElyz/G41ciR8LCavaDfU\nLLjvNXHfEaCF37fv+/9gMnJgGcfvHa6EGRj+T8W3ASfTXzdF3dtmolwZpWyV\n1Q40tBGxhTkS0cTbTzc10ySPBvZSIQ2RA7cdVH/cUFmJxpPHFfZCV0ndRYD3\ndYXL\r\n=f/Bo\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","readme":"# BloomReach Experience SDK for React\n\nSDK for powering content and components in React applications by [BloomReach Experience](https://www.bloomreach.com/en/products/experience). \nThis library makes integrating a React app with BloomReach Experience a breeze. It supports both client-side- and \nserver-side rendered/isomorphic React apps. \n\nBloomReach Experience allows you to use an external front-end such as React for rendering while still providing a \nnative-like authoring experience, such as integrated preview, in-context editing, drag & drop, server-side \npersonalization. For more information on this approach, see [A new approach to integrating SPA's with WCM: Fixing what's \nwrong with headless integrations](https://www.bloomreach.com/en/blog/2018/03/a-new-approach-to-integrating-spas-with-wcm-fixing-what%E2%80%99s-wrong-with-headless-integrations.html).\n\n## Install\n\n```bash\nnpm install bloomreach-experience-react-sdk --save\n```\n\n## Usage\n\n```js\nimport React from 'react'\nimport { CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\nconst componentDefinitions = {\n  \"MyCustomComponent\": { component: MyCustomComponent }\n}\n\nclass MyApp extends React.Component {\n  render() {\n    const currentUrl = window.location.href.pathname\n    return (\n      <CmsPage componentDefinitions={componentDefinitions} url={currentUrl}>\n        { () =>\n          <RenderCmsComponent />\n        }\n      </CmsPage>\n    )\n  }\n}\n```\n\nAt a minimum, `<CmsPage>` and `<RenderCmsComponent>` should be imported.\n\n`<CmsPage>` fetches the Page Model if it is not supplied as a prop (see section on server-side rendering); it fetches \nupdates on component changes in the CMS; and it initializes and manages state, and provides this as context to \n`<RenderCmsComponent>`.\n\n`<RenderCmsComponent>` renders components based on the Page Model API response.\n\nThe `<CmsPage>` component can be put anywhere within a React App. It functions as a higher-order component (HOC). \n`<RenderCmsComponent>` consumes the state from `<CmsPage>` and renders the components and any content refereced from the \ncomponents as contained in the Page Model API response. The `<RenderCmsComponent>` should be placed in the React app at \nthe exact location where you want BloomReach Experience to render its components.\n\nPlease note that `<CmsPage>` takes children as a function instead of as a prop, because it is otherwise not possible to \nprovide state through context providers due to a bug in React currently. So make sure to wrap any children of \n`<CmsPage>` in a function, as in the following example:\n\n ```js\n{ () =>\n  // any children go here\n  <h1>Blooming is what I do</h1>\n}\n ```\n\n`<CmsPage>` takes two props: `componentDefinitions` and `urlPath`.\n\nThe `urlPath` prop is used to fetch the Page Model for the page that is active; and to detect whether preview is active \nso that meta-data for Channel Manager functionality (e.g. in-context editing) is included in the HTML, and consequently \nChannel Manager functionality is enabled.\n\nFinally, component definitions are supplied through the `componentDefinitions` prop. The component definitions tell \n`<RenderCmsComponent>` what React component to render by mapping these to the *hst:label* of a CMS catalog component.\n\n## Server-side rendering\n\nFor server-side rendering (e.g. using [Next.js](https://github.com/zeit/next.js)) you need to fetch the Page Model API \nserver-side and supply it as a prop to `<CmsPage>`. Apart from this the usage is the same as with client-side rendering.\n\nThe helper function `getApiUrl()` can be used to generate the Page Model API URL using the current URL.\n\nIt is important to pass cookies from the initial request and supply these with the request header of the Page \nModel API request. Otherwise you will get a 403 error in preview mode.\n\nFinally, to get preview to work for server-side rendered apps you can use a reverse proxy to route requests from \nBloomReach's site preview to the React App-server. For more details, see section *3.2 Server-side apps* of the Hippo Lab: \n[Integrate a React application with BloomReach Experience](https://www.onehippo.org/labs/integrate-a-react-application-with-bloomreach-experience.html).\n\n```js\nimport fetch from 'isomorphic-unfetch'\nimport { getApiUrl, CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\n// setting pageModel to empty list instead of null value,\n// as otherwise the API will be fetched client-side again after server-side fetch errors\nlet pageModel = {}\n\nconst url = getApiUrl(asPath, {})\n// pass cookies of initial request for CMS preview\nconst response = await fetch(url, {headers: {'Cookie': req.headers.cookie}})\n\nif (response.ok) {\n  try {\n    pageModel = await response.json()\n  } catch (err) {\n    console.log(`Error! Could not convert response to JSON for URL: ${url}`)\n  }\n} else {\n  console.log(`Error! Status code ${response.status} while fetching CMS page data for URL: ${url}`)\n}\n```  \n\n## Creating custom components\n\nAny components that are supplied through the `compenentDefinitions` prop can be any type of valid React component, \nincluding functional components. Props are passed to these components as context so that you can access the components' \nconfiguration, content, etc. See more information below.\n\n### Props\n\nThe following props are passed to a component that is rendered by `<RenderCmsComponent>`:\n- `configuration` - `Object` component configuration. Contains the contributed models, raw parameters and resolved \n parameters. Content included in the component's model is not serialized as part of the component's configuration but in \n a separate content object, and a JSON Pointer reference is used to link to the actual content object. This is done to \n prevent content from being included multiple times in the API response when referenced multiple times. \n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview is active based on current URL supplied through `urlPath` prop of \n`<CmsPage>`.\n\nFor more information on the Page Model API response, see the [Swagger documentation](https://www.onehippo.org/library/concepts/spa-plus/page-model-api/swagger-api-documentation.html).\n\n### Example\n\n```js\nimport React from 'react'\nimport NewsItem from './news-item'\nimport { getNestedObject } from 'bloomreach-experience-react-sdk'\n\nexport default class NewsList extends React.Component {\n  render() {\n    const preview = this.props.preview\n    const pageModel = this.props.pageModel\n    const configuration = this.props.configuration\n\n    // return placeholder if no list is set on component\n    const list = getNestedObject(configuration, ['models', 'pageable', 'items'])\n    if (!list && preview) {\n      return (<p>Click to configure {configuration.label}</p>)\n    } else if (!list) {\n      // don't render placeholder outside of preview mode\n      return null\n    }\n\n    // build list of news articles\n    const listItems = list.map((listItem, index) => {\n      if ('$ref' in listItem) {\n        return (<NewsItem contentRef={listItem.$ref} pageModel={pageModel} preview={preview} key={index}/>)\n      }\n    })\n\n    return (\n      <div className=\"row\">\n        <div className=\"col-sm-12 news-list\">\n          {listItems}\n        </div>\n      </div>\n    )\n  }\n}\n```\n\n### Content components\n\nComponents that reference a single content-item (e.g. the Banner component) can use a convenient wrapper-class that \nlooks up the content and passes it as a prop. See below.\n\nTo enable this, the property `wrapInContentComponent: true` has to be set on the component in the `componentDefinitions` \nprop. See `componentDefinitions` in the API section for more details.\n\n#### Props\n\n- `content` - `Object` raw content object that contains the content-item's fields and field-values. Any references to \n other content-items (e.g. images) are serialized as JSON Pointers.\n- `manageContentButton` - `React.Component` for placement and rendering of the [Manage Content Button](https://www.onehippo.org/library/concepts/component-development/render-manage-content-button.html)\n in preview mode in CMS.\n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview is active based on current URL supplied through `urlPath` prop of \n`<CmsPage>`.\n\n#### Example\n\n```js\nimport React from 'react'\n\nconst content = this.props.content;\nconst manageContentButton = this.props.manageContentButton;\n\nclass Banner extends React.Component {\n  render() {\n    return (\n      <div className=\"my-content-component\">\n        { manageContentButton && manageContentButton }\n        { content.title && content.title }\n      </div>)\n  }\n}\n```\n\n### More component examples\n\nFor more detailed examples, see the components included in the [example applications](https://github.com/bloomreach/experience-react-sdk/tree/master/examples/client-side-rendered/src/components). \n\n### Helper functions\n\nAdditionally, there are a variety of helper functions available. See the examples below. For full details on the APIs, \nsee the API section.\n\n```js\nimport { createLink, getImageUrl, getNestedObject, parseAndRewriteLinks, parseDate } from 'bloomreach-experience-react-sdk'\n\nconst link = createLink('ref', link, linkText, className)\nconst image = getImageUrl(content.image, this.props.pageModel)\nconst list = getNestedObject(configuration, ['models', 'pageable', 'items', 0])\nconst contentHtml = parseAndRewriteLinks(content.content.value)\nconst date = parseDate(content.date)\n```\n\n## API\n\n### `<CmsPage>`\n\nThe CmsPage component is a higher-order component that takes care of:\n- Fetching the Page Model for client-side rendering, when not supplied as a prop.\n- Fetching Page Model updates on component changes in the CMS.\n- Initializing and managing state, and providing this as context to `<RenderCmsComponent>`.\n\n#### Properties\n\n- `cmsUrls` - `Object` Override default CMS URL's. (Optional)\n- `componentDefinitions` - `object` Mapping of CMS catalog components to React components. Determines what \ncomponent to render based from the Page Model. (Optional)\n- `createLink` - `Function` Called when creating internal links so that links can be constructed using the router \nlibrary of the React app. (Optional)\n- `pageModel` - `Object` Supply Page Model as prop. Used for server-side-rendering where Page Model API is fetched \nserver-side. When supplied, `CmsPage` will not fetch Page Model API on mount, only on component updates in CMS.\n(Optional)\n- `urlPath` - `String` Current URL-path for determining if preview mode is active, and for fetching the Page Model for \nthe page that is active. (Required)\n\n###### `cmsUrls` property\n\nProperty that allows you to override the default URL's for fetching the Page Model API. Typically you will only have to \ndefine `cmsScheme`, `cmsHostname`, `cmsPort`, and `cmsContextPath`. Input object takes the following properties (all are \noptional):\n- `cmsScheme` - `String` scheme (default: *http*)\n- `cmsHostName` - `String` hostname (default: *localhost*)\n- `cmsPort` - `number` port number (default: *8080*)\n- `cmsContextPath` - `String` site context-path (default: *site*)\n- `cmsChannelPath` - `String` path to the used channel, if channel is accessed through a subpath\n- `cmsPreviewPrefix` - `String` preview-prefix used by CMS (default: *_cmsinternal*)\n- `cmsApiPath` - `String` path to Page Model API as subpath (default: *resourceapi*)\n- `cmsApiComponentRenderingUrlSuffix` - `String` (default: *?_hn:type=component-rendering&_hn:ref=*)\n\n###### `componentDefinitions` property\n\nMaps CMS catalog components to React components. Expects input object with *hst:label* of the CMS components as keys and \nReact components as values.\n\nAdditionally, see example below:\n\n```js\nconst componentDefinitions = {\n  \"MyCustomCmsComponent\": { component: MyCustomReactComponent },\n  \"AnotherCmsComponent\": { component: AnotherReactComponent, wrapInContentComponent: true }\n};\n```\n\n##### `createLink` property\n\nCalled when creating internal links so that links can be constructed using the router \nlibrary of the React app. \n\nTakes `Function` as input. The function should return valid JSX and have three parameters:\n- `href` - `String` href of link\n- `linkText` - `Function` contains the HTML that is wrapped inside the link. Is a function so that it can include HTML.\n- `className` - `String` classnames to add to the link element\n\nFor example:\n```js\nconst createLink = (href, linkText, className) => {\n  return (<Link className={className} to={href}>{linkText()}</Link>)\n}\n```\n\n##### `pageModel` property\n\nPage Model can be supplied as a prop when using a server-side rendered / isomorphic React framework. When supplied, \n`<CmsPage>` will not fetch the Page Model API client-side. \n\n##### `urlPath` property\n\nTakes `String` as input. Should only contain the URL-path (everything that comes after the hostname or domain name).\n\n### `<RenderCmsComponent>`\n\nRenders a CMS component and all of its children using the Page Model supplied by `<CmsPage>`. Will render the entire \nPage Model by default.\n\n#### Properties\n\n- `path` - `String` path to a component (static CMS component), container or container-item in the Page Model to render \nonly that component and its children. If no path is supplied, entire Page Model will be rendered. \n\n#### Example\n\n```js\n<RenderCmsComponent path={'main/container/banner'}/>\n```\n\n### `getApiUrl(urlPath, [newCmsUrls])`\n\nHelper function for generating URL to the Page Model API for server-side fetching of the Page Model. \n\n#### Arguments\n\n- `urlPath` - `String` URL-path (everything that comes after the hostname or domain name).\n- `newCmsUrls` - `Object` takes `cmsUrls` property as input to override default CMS URL's\n\n#### Return types\n\n`String` returns URL for fetching Page Model API\n\n### `createLink(linkType, link, linkText, className)`\n\nCreates a link to either a component or content-item itself or a referenced content-item (can be a document, image or \nasset) and returns the link as JSX.  \n\n#### Arguments\n\n- `linkType` - `String` type of link to create. Valid values are `self`, `ref` or `href`.\n  - `self` - Create link to the component or content-item itself. E.g. for a news-item in a news overview.\n  - `ref` - Create link to a referenced content-item. E.g. for a banner.\n  - `href` -  Used by `parseAndRewriteLinks()` to create links using a href only.\n- `link` - `Object` the component configuration or content-object that is linking to itself or referenced another \ncontent-item.\n- `linkText` - `JSX | Function` HTML to wrap inside the link. Is a function so that it can include HTML.\n- `className` - `String` classnames to add to the link element\n\n#### Return types\n\n`JSX` returns link as JSX object that can be included as a variable anywhere within the return section of a React \ncomponent's render method.\n\n### `getImageUrl(imageRef, pageModel)`\n\nCreates link to URL of image in case BloomReach Experience is used for serving images.\n\n#### Arguments\n\n- `imageRef` - `String` JSON Pointer that references the image.\n- `pageModel` - `Object` since this function is a pure JavaScript function it can't get Page Model from context, so it \nhas to be provided as function parameter. The Page Model is used to retrieve the image.\n\n#### Return types\n\n`String` returns URL to image.\n\n### `getNestedObject(nestedObject, pathArray)`\n\nReturns a nested object or value using a path array. Useful when you need to access deeply nested objects/values without\nhaving to string null checks together.\n\n#### Arguments\n\n- `nestedObject` - `Object` the object containing the nested object or value.\n- `pathArray` - `Array` contains the path to the nested object as an array.\n\n#### Return types\n\n`Object|null` returns the nested object if found, otherwise returns null. \n\n### `parseAndRewriteLinks(html)`\n\nParses HTML of a rich-text field of a content-item for rewriting links in HTML to internal links. Uses the `createLink` \nfunction passed to `<CmsPage>` for constructing internal links.\n\n#### Arguments\n\n- `html` - `String` value of rich-text field of a content-item. Should contain HTML only.\n\n#### Return types\n\n`JSX` returns parsed and rewrited HTML as JSX.\n\n### `parseDate(date)`\n\nParses date-field of a content item and returns date as a string.\n\n#### Arguments\n\n- `date` - `String` takes raw value of a date-field as input, following the ISO 8601:2000 format.\n\n#### Return types\n\n`String` returns date in full date format.\n\n## FAQ / Troubleshooting\n\nNothing here yet :)\n\n## Author\n\nRobbert Kauffman - BloomReach\n","gitHead":"e747a98902fe8c0e63544f26bc570dcd7f124822","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"rkauffman","email":"robbertkauffman@gmail.com"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.1.0","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.6.0","dependencies":{"jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.1.1-rc1_1532547293359_0.025227440883010877","host":"s3://npm-registry-packages"}},"0.1.1":{"name":"bloomreach-experience-react-sdk","version":"0.1.1","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.1.1","maintainers":[{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"29a5f161120b85a85dcd179f0ae6da88d6ae230e","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.1.1.tgz","fileCount":28,"integrity":"sha512-uo+yu/G8PEoCXRgKrzsmtnLLk3s0YSpxNlGLe5Kiy9PAVqeYlcpayUxsXXl+pkQ3ZMlOm79B1IPk3oFccTR31g==","signatures":[{"sig":"MEUCIEO5yfzEa6qbrBGV8NXefAU33ai/yfxqWplHGLxpBvyOAiEA8RnCurAhxzg/OBJJWPF6VE/Uo4kuVCB89LkrOWD1zUY=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":233577,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbWNazCRA9TVsSAnZWagAAROAP/iqFr5hdTd9mtEPT0HV1\nY2sAHnJy9gkRZQ6HXrHjDcl83RvZXsd1Vzhn6ffO+ylFyLfwFsOTZTm805XY\nZRtFgPWJ6z2ximT4yi7c763HuWEDGfiYcffob+febKvXR9hQh/EmV8RQ1Y3l\nSJEURbQIobjGTxIayeCMgEwAhKxXy2kpXzwzZKZO9u/q9LbExZTge9VWQK9P\nnZH9NyksLsCJ2VJX8N56kOjlHfY2b6TpiN3WfX12tbt8nDnZC2v4WiKAJBbS\nPugwHS3J1xctRrIsRIMSI7ucsjDgpSBhOce2OzhcBhjDkzlcN3pnR7FT9vsg\nihWNXpRxRPuFoA7WVISJzL6J8hDnP/s7Y4UT3I6fAu3cmIK06PILATHceo3r\nz0HsOr+Ub2UROuzIYIq67orCwJG7hAgKcZG7s/iQhEgdP6orzs7SiXFI7Tuf\nI5qVSRLCVNYQcPTdZLVI9ufLZO43T49mhLFM8tr4FnC0kV5IwC0OKjquEyno\ncyXYa8jmPaRejttpyjcwmjYTcA7F8hMY2sCJ3gMRn0rscQzwH1cu1Wdf1iy4\neeTwvBYgNWlqP1ooxTd7h1k3nFg6hp+h5eCDnjNPXbimWHsXuo6FQp3CwBLO\n2MtTlF8Mj1GQAx8ry/a766SzHunzSu1TPWOfRE8lt5vm3NJPpZWF8HLFQcFA\nrUIg\r\n=l1Qg\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","gitHead":"5afd183f8fe2dc06bc28682236cee6f75752023c","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"rkauffman","email":"robbertkauffman@gmail.com"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.1.0","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.6.0","dependencies":{"jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.1.1_1532548786945_0.643690415322737","host":"s3://npm-registry-packages"}},"0.1.2":{"name":"bloomreach-experience-react-sdk","version":"0.1.2","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.1.2","maintainers":[{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"843ff1a1c6095ddb2dd4053817d2178fa3f92838","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.1.2.tgz","fileCount":28,"integrity":"sha512-fxj+DZF4OPpauEITsT78MHeE6TpUJMFan2NKlmtP86EDH+2Gp2Eter8gBNnJHFXOac310C/ZjdtbcIw4LAgokw==","signatures":[{"sig":"MEUCIQD1TmdVMyjhZayWNvSUuNzTEC5Gk+NLeEqb+yNT6beZVwIgNSmj6JxxJFksOf1USw/3OPvM8XEB8Uwn4pEVa69+4AE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":234127,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbYb9tCRA9TVsSAnZWagAAADwP/RQHKpmAmmHF0LJCxKbS\nKY2eNw/7oVUoy9nFB2kklllOWahq1+GRLx308iERztOvtplcOTzVIE6nFOfR\nTK7iP86zbfQNNNlnEhQiLhMBbcNvcnSB3Pnht4aXMXmLAJcpJnMIRK8dgySm\n/l1rynozGfohK24SiPXznb4mCuNY9F9BDjAYSH/7eVnCkV4rUsqryI1p2Qqk\npTwPonxyTtfuHd/zjdCrrWVU+4lZm8s9NaqWh5LCOPFFdDy1oIMWvMKHJS65\nH/B+6Q0x+HBnQg2TnL3SsBVJ/MHb58ouMAi07S2m3y5wuP3bcP6j9RKxYCgZ\nrrdnuWOuzd0sezSJdoAAPN8TEIdU66IQ4+MDZsuFgoQQ5zSMAzKZmquVoa/u\n6k0Q2TyhywCYPp2AOuibU6KqcXma41XuANFLFossOjlBxmPmheGpLKZwnlfL\nVyTt6FJTZPmNMfX3adv8/zfsa8IpSwkMMcrCfwHYN7TEOcq+7q7xMaEg9ydl\nXyUdjlwMwZx7uApk1TSRKDn/orfyZJVqIimeJlVKZf7yjdi1yUb8oKAKa9ge\nIJTwouF1k6SjuTWtCvjyCtXieN/se808pOCSsZyb9Zuqc7ZDRbsp8BSqn2eO\nmMw2WTAy85fkfF9k2Hw2V1VCo5XltgkUrzHUJ6fYtPGF37ThyFkDjRKA4ZH3\ngAgU\r\n=yOWo\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","gitHead":"3cc16b33044df75c1103ebd76c281b8af67992dc","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"rkauffman","email":"robbertkauffman@gmail.com"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.1.0","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.6.0","dependencies":{"jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.1.2_1533132652622_0.7962345043222825","host":"s3://npm-registry-packages"}},"0.2.0-rc1":{"name":"bloomreach-experience-react-sdk","version":"0.2.0-rc1","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.2.0-rc1","maintainers":[{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"fddf13424f1e0fec5d78323dfab9c1a775f84d58","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.2.0-rc1.tgz","fileCount":28,"integrity":"sha512-h9xpK8zlovtJhbIB3icVxHSpPsKgJPMlX8vhbcWszaBEXuqhx4knNII0l9X8sPMiVK2s+F4hqbjOJzSV6emg1w==","signatures":[{"sig":"MEUCIQDhiVjCDy8eGsdKkwcEoBSvkPZqxcC3yIM8uVJY+8JGNgIgdLQlSBVoA+XEpgy8fM/MnfJqZtr6f9VQ5J6eoMX+np0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":238974,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbdeXLCRA9TVsSAnZWagAAqXkP/0IJHNG+YmrFC6dly6uC\nn/TDDYWvdvAZOMyRTVnipKJYb4+xBfPiqG5lLLyIKyEcAKhmU8zt4dsw7k2z\nFycS6d1od7Gzwho1KQ8ItIKKc4rHzGAp1HK+bS6mtcPu6rvxUSIiRw+dnVrM\ntLdC6/aAWqUvHU91m5vHN9AO2wcokrbinn/LJQZOJcAZJ/if9P44sKFdXq/f\n3SEl662DpVPH/96TftC4DFg3eJEfH5IaxmCL98RLJSzD0bghLEfXFD8OVYim\nicWveAWrpMUin/fP9+oB2ccF++NB2PbQpzB31pk/Jp2x4CnRtiPunkGuFgj1\nfVKLKKbXq76lxQX2y7qqO45A9MXvoFCWkQVmCGqC/ZjRCvfaHmhDPELZhzHU\nj8im77VN2A71ZqIy7c4GY/JEtUeoBnezKqxwQ4AZoJrZn2APZwXNVpmXph3W\n83kOPuLCd4lzLoL5xnAZF27XedoSd1FptoZF5ZVVEV/spEOLNy5p0AVArMZO\n2Twj73gEvBMEU16wRpVuXMBaEkpCezIFkgGgPcMqJzjoMpC6rWK1r9/sajI5\nNrHWO1KzXyT5tOKu+w0mgTrGed0zmHJT2cRnO4AQQ+mj6hprfjexbdT8GDxZ\no3aQPB+Ug7Beu0D4GSPx7AhTHM5NNXRu+pjAqc550Ef+l0Osf20EYmyqhlT7\no6md\r\n=+TZ1\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","readme":"# BloomReach Experience SDK for React\n\nSDK for powering content and components in React applications by [BloomReach Experience](https://www.bloomreach.com/en/products/experience). \nThis library makes integrating a React app with BloomReach Experience a breeze. It supports both client-side- and \nserver-side rendered/isomorphic React apps. \n\nBloomReach Experience allows you to use an external front-end such as React for rendering while still providing a \nnative-like authoring experience, such as integrated preview, in-context editing, drag & drop, server-side \npersonalization. For more information on this approach, see [A new approach to integrating SPA's with WCM: Fixing what's \nwrong with headless integrations](https://www.bloomreach.com/en/blog/2018/03/a-new-approach-to-integrating-spas-with-wcm-fixing-what%E2%80%99s-wrong-with-headless-integrations.html).\n\n## Install\n\n```bash\nnpm install bloomreach-experience-react-sdk --save\n```\n\n## Usage\n\n```js\nimport React from 'react'\nimport { CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\nconst componentDefinitions = {\n  \"MyCustomComponent\": { component: MyCustomComponent }\n}\n\nclass MyApp extends React.Component {\n  render() {\n    const request = { hostName: window.location.hostname, path: window.location.pathname };\n    return (\n      <CmsPage componentDefinitions={componentDefinitions} request={request}>\n        { () =>\n          <RenderCmsComponent />\n        }\n      </CmsPage>\n    )\n  }\n}\n```\n\nAt a minimum, `<CmsPage>` and `<RenderCmsComponent>` should be imported.\n\n`<CmsPage>` fetches the Page Model if it is not supplied as a prop (see section on server-side rendering); it fetches \nupdates on component changes in the CMS; and it initializes and manages state, and provides this as context to \n`<RenderCmsComponent>`.\n\n`<RenderCmsComponent>` renders components based on the Page Model API response.\n\nThe `<CmsPage>` component can be put anywhere within a React App. It functions as a higher-order component (HOC). \n`<RenderCmsComponent>` consumes the state from `<CmsPage>` and renders the components and any content referenced from \nthe components as contained in the Page Model API response. The `<RenderCmsComponent>` should be placed in the React app \nat the exact location where you want BloomReach Experience to render its components.\n\nPlease note that `<CmsPage>` takes children as a function instead of as a prop, because it is otherwise not possible to \nprovide state through context providers due to a bug in React currently. So make sure to wrap any children of \n`<CmsPage>` in a function, as in the following example:\n\n ```js\n{ () =>\n  // any children go here\n  <h1>Blooming is what I do</h1>\n}\n ```\n\n`<CmsPage>` takes two props: `componentDefinitions` and `request`.\n\nThe `request` prop is used to fetch the Page Model for the page that is active; and to detect whether preview is active \nso that meta-data for Channel Manager functionality (e.g. in-context editing) is included in the HTML, and consequently \nChannel Manager functionality is enabled.\n\nFinally, component definitions are supplied through the `componentDefinitions` prop. The component definitions tell \n`<RenderCmsComponent>` what React component to render by mapping these to the *hst:label* of a CMS catalog component.\n\n## Server-side rendering\n\nFor server-side rendering (e.g. using [Next.js](https://github.com/zeit/next.js)) you need to fetch the Page Model API \nserver-side and supply it as a prop to `<CmsPage>`. Apart from this the usage is the same as with client-side rendering.\n\nThe helper function `getApiUrl()` can be used to generate the Page Model API URL using the current request.\n\nIt is important to pass cookies from the initial request and supply these with the request header of the Page \nModel API request. Otherwise you will get a 403 error in preview mode.\n\nFinally, to get preview to work for server-side rendered apps you can use a reverse proxy to route requests from \nBloomReach's site preview to the React App-server. For more details, see section *3.2 Server-side apps* of the Hippo Lab: \n[Integrate a React application with BloomReach Experience](https://www.onehippo.org/labs/integrate-a-react-application-with-bloomreach-experience.html).\n\n```js\nimport fetch from 'isomorphic-unfetch'\nimport { getApiUrl, CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\n// setting pageModel to empty list instead of null value,\n// as otherwise the API will be fetched client-side again after server-side fetch errors\nlet pageModel = {}\n\nconst request = { hostname: req.headers.host, path: asPath }\nconst url = getApiUrl(request, {})\n// pass cookies of initial request for CMS preview\nconst response = await fetch(url, {headers: {'Cookie': req.headers.cookie}})\n\nif (response.ok) {\n  try {\n    pageModel = await response.json()\n  } catch (err) {\n    console.log(`Error! Could not convert response to JSON for URL: ${url}`)\n  }\n} else {\n  console.log(`Error! Status code ${response.status} while fetching CMS page data for URL: ${url}`)\n}\n```  \n\n## Example React apps\n\nThere are two example React apps available that use the SDK. One client-side rendered, and one server-side rendered \nusing [Next.js](https://github.com/zeit/next.js). You can find the [example apps on Github](https://github.com/bloomreach/experience-react-sdk/tree/master/examples).\n\n## Creating custom components\n\nAny components that are supplied through the `compenentDefinitions` prop can be any type of valid React component, \nincluding functional components. Props are passed to these components as context so that you can access the components' \nconfiguration, content, etc. See more information below.\n\n### Props\n\nThe following props are passed to a component that is rendered by `<RenderCmsComponent>`:\n- `configuration` - `Object` component configuration. Contains the contributed models, raw parameters and resolved \n parameters. Content included in the component's model is not serialized as part of the component's configuration but in \n a separate content object, and a JSON Pointer reference is used to link to the actual content object. This is done to \n prevent content from being included multiple times in the API response when referenced multiple times. \n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview is active based on current URL supplied through `request` prop of \n`<CmsPage>`.\n\nFor more information on the Page Model API response, see the [Swagger documentation](https://www.onehippo.org/library/concepts/spa-plus/page-model-api/swagger-api-documentation.html).\n\n### Example\n\n```js\nimport React from 'react'\nimport NewsItem from './news-item'\nimport { getNestedObject } from 'bloomreach-experience-react-sdk'\n\nexport default class NewsList extends React.Component {\n  render() {\n    const preview = this.props.preview\n    const pageModel = this.props.pageModel\n    const configuration = this.props.configuration\n\n    // return placeholder if no list is set on component\n    const list = getNestedObject(configuration, ['models', 'pageable', 'items'])\n    if (!list && preview) {\n      return (<p>Click to configure {configuration.label}</p>)\n    } else if (!list) {\n      // don't render placeholder outside of preview mode\n      return null\n    }\n\n    // build list of news articles\n    const listItems = list.map((listItem, index) => {\n      if ('$ref' in listItem) {\n        return (<NewsItem contentRef={listItem.$ref} pageModel={pageModel} preview={preview} key={index}/>)\n      }\n    })\n\n    return (\n      <div className=\"row\">\n        <div className=\"col-sm-12 news-list\">\n          {listItems}\n        </div>\n      </div>\n    )\n  }\n}\n```\n\n### Content components\n\nComponents that reference a single content-item (e.g. the Banner component) can use a convenient wrapper-class that \nlooks up the content and passes it as a prop. See below.\n\nTo enable this, the property `wrapInContentComponent: true` has to be set on the component in the `componentDefinitions` \nprop. See `componentDefinitions` in the API section for more details.\n\n#### Props\n\n- `content` - `Object` raw content object that contains the content-item's fields and field-values. Any references to \n other content-items (e.g. images) are serialized as JSON Pointers.\n- `manageContentButton` - `React.Component` for placement and rendering of the [Manage Content Button](https://www.onehippo.org/library/concepts/component-development/render-manage-content-button.html)\n in preview mode in CMS.\n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview is active based on current URL supplied through `request` prop of \n`<CmsPage>`.\n\n#### Example\n\n```js\nimport React from 'react'\n\nconst content = this.props.content;\nconst manageContentButton = this.props.manageContentButton;\n\nclass Banner extends React.Component {\n  render() {\n    return (\n      <div className=\"my-content-component\">\n        { manageContentButton && manageContentButton }\n        { content.title && content.title }\n      </div>)\n  }\n}\n```\n\n### More component examples\n\nFor more detailed examples, see the components included in the [example applications](https://github.com/bloomreach/experience-react-sdk/tree/master/examples/client-side-rendered/src/components). \n\n### Helper functions\n\nAdditionally, there are a variety of helper functions available. See the examples below. For full details on the APIs, \nsee the API section.\n\n```js\nimport { createLink, getImageUrl, getNestedObject, parseAndRewriteLinks, parseDate } from 'bloomreach-experience-react-sdk'\n\nconst link = createLink('ref', link, linkText, className)\nconst image = getImageUrl(content.image, this.props.pageModel, this.props.preview)\nconst list = getNestedObject(configuration, ['models', 'pageable', 'items', 0])\nconst contentHtml = parseAndRewriteLinks(content.content.value, this.props.preview)\nconst date = parseDate(content.date)\n```\n\n## API\n\n### `<CmsPage>`\n\nThe CmsPage component is a higher-order component that takes care of:\n- Fetching the Page Model for client-side rendering, when not supplied as a prop.\n- Fetching Page Model updates on component changes in the CMS.\n- Initializing and managing state, and providing this as context to `<RenderCmsComponent>`.\n\n#### Properties\n\n- `cmsUrls` - `Object` Override default CMS URL's. (Optional)\n- `componentDefinitions` - `object` Mapping of CMS catalog components to React components. Determines what \ncomponent to render based from the Page Model. (Optional)\n- `createLink` - `Function` Called when creating internal links so that links can be constructed using the router \nlibrary of the React app. (Optional)\n- `pageModel` - `Object` Supply Page Model as prop. Used for server-side-rendering where Page Model API is fetched \nserver-side. When supplied, `CmsPage` will not fetch Page Model API on mount, only on component updates in CMS.\n(Optional)\n- `request` - `String` Current URL-path for determining if preview mode is active, and for fetching the Page Model for \nthe page that is active. (Required)\n\n###### `cmsUrls` property\n\nProperty that allows you to override the default URL's for fetching the Page Model API. Typically you will only have to \ndefine `scheme`, `hostname`, `port`, and `contextPath`. Input object takes the following properties (all are \noptional):\n- `scheme` - `String` scheme (default: *http*)\n- `hostname` - `String` hostname (default: *localhost*)\n- `port` - `number` port number (default: *8080*)\n- `contextPath` - `String` site context-path (default: *site*)\n- `channelPath` - `String` path to the used channel, if channel is accessed through a subpath\n- `previewPrefix` - `String` preview-prefix used by CMS (default: *_cmsinternal*)\n- `apiPath` - `String` path to Page Model API as subpath (default: *resourceapi*)\n- `apiComponentRenderingUrlSuffix` - `String` (default: *?_hn:type=component-rendering&_hn:ref=*)\n\n###### `componentDefinitions` property\n\nMaps CMS catalog components to React components. Expects as input an object with `hst:label` of the CMS components as \nkeys and as value another object. The nested object has the mandatory property `component` who's value maps the CMS \ncomponent to a React component. See the example below:\n\n```js\nconst componentDefinitions = {\n  \"MyCustomCmsComponent\": { component: MyCustomReactComponent },\n  \"AnotherCmsComponent\": { component: AnotherReactComponent, wrapInContentComponent: true }\n};\n```\n\nAdditionally, the property `wrapInContentComponent: true` can be used for components \nthat reference a single content-item. When this property is set on a component, it will be wrapped in a convenient \nwrapper class. See section *Content components*.\n\n##### `createLink` property\n\nCalled when creating internal links so that links can be constructed using the router \nlibrary of the React app. \n\nTakes `Function` as input. The function should return valid JSX and have three parameters:\n- `href` - `String` href of link\n- `linkText` - `Function` contains the HTML that is wrapped inside the link. Is a function so that it can include HTML.\n- `className` - `String` classnames to add to the link element\n\nFor example:\n```js\nconst createLink = (href, linkText, className) => {\n  return (<Link className={className} to={href}>{linkText()}</Link>)\n}\n```\n\n##### `pageModel` property\n\nPage Model can be supplied as a prop when using a server-side rendered / isomorphic React framework. When supplied, \n`<CmsPage>` will not fetch the Page Model API client-side. \n\n##### `request` property\n\nTakes `Object` as input with properties `hostname` and `path`, both of type `String`. The property \n`hostname` should contain the hostname for the current request (client-side this is window.location.hostname). The \nproperty `path` should contain the URL-path for the current request (client-side this is window.location.pathname);\n\n### `<RenderCmsComponent>`\n\nRenders a CMS component and all of its children using the Page Model supplied by `<CmsPage>`. Will render the entire \nPage Model by default.\n\n#### Properties\n\n- `path` - `String` path to a component (static CMS component), container or container-item in the Page Model to render \nonly that component and its children. If no path is supplied, entire Page Model will be rendered. \n\n#### Example\n\n```js\n<RenderCmsComponent path={'main/container/banner'}/>\n```\n\n### `getApiUrl(request, [newCmsUrls])`\n\nHelper function for generating URL to the Page Model API for server-side fetching of the Page Model. \n\n#### Arguments\n\n- `request` - `Object` containing hostname and URL-path as properties `hostname` and `path` respectively. See the \n`request` property section above.\n- `newCmsUrls` - `Object` takes `cmsUrls` property as input to override default CMS URL's\n\n#### Return types\n\n`String` returns URL for fetching Page Model API\n\n### `createLink(linkType, link, linkText, className)`\n\nCreates a link to either a component or content-item itself or a referenced content-item (can be a document, image or \nasset) and returns the link as JSX.  \n\n#### Arguments\n\n- `linkType` - `String` type of link to create. Valid values are `self`, `ref` or `href`.\n  - `self` - Create link to the component or content-item itself. E.g. for a news-item in a news overview.\n  - `ref` - Create link to a referenced content-item. E.g. for a banner.\n  - `href` -  Used by `parseAndRewriteLinks()` to create links using a href only.\n- `link` - `Object` the component configuration or content-object that is linking to itself or referenced another \ncontent-item.\n- `linkText` - `JSX | Function` HTML to wrap inside the link. Is a function so that it can include HTML.\n- `className` - `String` classnames to add to the link element\n\n#### Return types\n\n`JSX` returns link as JSX object that can be included as a variable anywhere within the return section of a React \ncomponent's render method.\n\n### `getImageUrl(imageRef, pageModel, preview)`\n\nCreates link to URL of image in case BloomReach Experience is used for serving images.\n\n#### Arguments\n\n- `imageRef` - `String` JSON Pointer that references the image.\n- `pageModel` - `Object` since this function is a pure JavaScript function it can't get Page Model from context, so it \nhas to be provided as function parameter. The Page Model is used to retrieve the image.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by `<RenderCmsComponent>` can \npass the prop `this.props.preview`.\n\n#### Return types\n\n`String` returns URL to image.\n\n### `getNestedObject(nestedObject, pathArray)`\n\nReturns a nested object or value using a path array. Useful when you need to access deeply nested objects/values without\nhaving to string null checks together.\n\n#### Arguments\n\n- `nestedObject` - `Object` the object containing the nested object or value.\n- `pathArray` - `Array` contains the path to the nested object as an array.\n\n#### Return types\n\n`Object|null` returns the nested object if found, otherwise returns null. \n\n### `parseAndRewriteLinks(html, preview)`\n\nParses HTML of a rich-text field of a content-item for rewriting links in HTML to internal links. Uses the `createLink` \nfunction passed to `<CmsPage>` for constructing internal links.\n\n#### Arguments\n\n- `html` - `String` value of rich-text field of a content-item. Should contain HTML only.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by `<RenderCmsComponent>` can \npass the prop `this.props.preview`.\n\n#### Return types\n\n`JSX` returns parsed and rewrited HTML as JSX.\n\n### `parseDate(date)`\n\nParses date-field of a content item and returns date as a string.\n\n#### Arguments\n\n- `date` - `String` takes raw value of a date-field as input, following the ISO 8601:2000 format.\n\n#### Return types\n\n`String` returns date in full date format.\n\n## Release notes\n\n### Version 0.2.0\n\nThis version includes significant changes. Please make sure to update your components using the upgrade steps further \ndown.\n- Changed `cmsUrls` property to support different live and preview URLs.\n- Changed `urlPath` property to `request` property which no longer takes URL-path as string, but an object with hostname \nand URL-path. This property should be passed to `<CmsPage>`.\n- Changed helper method `getApiUrl()` to take `request` property as parameter instead of `urlPath`.\n- Changed helper method `parseAndRewriteLinks()` to take an extra parameter: `preview`.\n- Changed helper method `getImageUrl()` to take an extra parameter: `preview`.\n\nUpgrade steps:\n- Modify `cmsUrls` property to include URLs for live and preview using the properties `live` and `preview` respectively.\nPlease note that the `cms` prefix has been removed from all URL properties. So `cmsHostname` has become `hostname`. \nPreview URLs are optional. For example:\n  ```js\n  const cmsUrls = {\n    live: {\n      hostname: bloomreach.com\n    },\n    preview: {\n      hostname: cms.bloomreach.com\n    }\n  }\n  ```\n- Pass current request details through `request` property to `<CmsPage>`. This was previously done through the `urlPath` \nproperty. The `request` property should be an object that contains the hostname and path as properties `hostname` and \n`path` respectively. For example:\n  ```js\n  const request = { hostname: window.location.hostname, path: window.location.path };\n  <CmsPage componentDefinitions={componentDefinitions} request={request}>\n  ```\n- Update usage of `getApiUrl` to pass `request` property (see previous bullet) instead of URL-path.\n- Update usage of helper methods `getImageUrl()` and `parseAndRewriteLinks()` to include the preview parameter. \nComponents rendered by `<RenderCmsComponent>` have the preview value passed as prop `this.props.preview`.\n\n## FAQ / Troubleshooting\n\nNothing here yet :)\n\n## Author\n\nRobbert Kauffman - BloomReach\n","gitHead":"8d462897a329164c0f7a1f3e803292e1107ddb00","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"rkauffman","email":"robbertkauffman@gmail.com"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.2.0","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.8.0","dependencies":{"jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.2.0-rc1_1534453194470_0.5751631048126276","host":"s3://npm-registry-packages"}},"0.2.0-rc2":{"name":"bloomreach-experience-react-sdk","version":"0.2.0-rc2","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.2.0-rc2","maintainers":[{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"0fe62737a69a8ea7809f6d1d5c91f5257c0f8211","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.2.0-rc2.tgz","fileCount":28,"integrity":"sha512-ycL2WoGv5v8XTY2PdNCYLReX65qRfzM9l2kQ12aumT2RAUfDUpzYQf2xujbrV063P0EmWtaqGXnwFeI2fh3REA==","signatures":[{"sig":"MEYCIQCoD7OXpAF5afE9Kgcd91ixxi0qbiVf0kzekD1Qok33rwIhAKKY0poOnindptX2n/Y84ITxkn/rJCcmpYWc5YTHYdyZ","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":238977,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbfYpQCRA9TVsSAnZWagAAuDYP/3jcka1n3JDDtzlzHRHd\niUgzrsOJrvc6ZIB4p4bJc5HfcbsxnG9TLrH0khBHRDjS726On2fTzhJSxf5T\nudvyoqgUL+9NN0i4aAkKSVUXv8l0nLEPs9bgf3n9SRk0QWSF/nZIQhwLWYUi\nAX2ksBtbXO9zPn5ZDWNWT6duKm5QHNPc55Ck0QiEeXQpIwyIer22NWNl68NT\nqyJcZFU+CYqLx4t3RPl3SAwsgB5QHhRIn7n9GzPQ70QD42pZmOyj+1XgF9sV\n9q6w3CjFAhRK78yASAlc8IaHMMeWY0+7R5RC6GkSZipHYJsFeoKn35Kebq0j\nzxIetli3q2Or0m64V2XOyqt5Sy8ZsYF6E5f3sUivc8s/hkOkqI1LYe+7XIUZ\ndJ1Yq4w1hFVa5Nf8OoKkImzl/HWo2Q0x10b6j1+S/Op47KRJx6JhdCI+hB1n\nynMptjFzpeCw25HWfXBbj0Z1/O/b6wUx74SwuKNneTWVneWmATlQjNaYasip\ni9flaUf+B8RnbeHTVe809gjQ7Q4z8d3Nu1MrhBnInYiNaha+ovUZr/CnAv64\nPQMYu7kFOkXkckcPrCr/aX6vRNsVQGwcYx+qhyXQQkeP7lKuhovJHKtm2bY9\nSJFGp0D5vxU7Gc+In5yf0SbLVC3ZeMaEXGaJHTnpIuW9l3F2bEopnzcrkfmw\nQ08s\r\n=2YC3\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","readme":"# BloomReach Experience SDK for React\n\nSDK for powering content and components in React applications by [BloomReach Experience](https://www.bloomreach.com/en/products/experience). \nThis library makes integrating a React app with BloomReach Experience a breeze. It supports both client-side- and \nserver-side rendered/isomorphic React apps. \n\nBloomReach Experience allows you to use an external front-end such as React for rendering while still providing a \nnative-like authoring experience, such as integrated preview, in-context editing, drag & drop, server-side \npersonalization. For more information on this approach, see [A new approach to integrating SPA's with WCM: Fixing what's \nwrong with headless integrations](https://www.bloomreach.com/en/blog/2018/03/a-new-approach-to-integrating-spas-with-wcm-fixing-what%E2%80%99s-wrong-with-headless-integrations.html).\n\n## Install\n\n```bash\nnpm install bloomreach-experience-react-sdk --save\n```\n\n## Usage\n\n```js\nimport React from 'react'\nimport { CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\nconst componentDefinitions = {\n  \"MyCustomComponent\": { component: MyCustomComponent }\n}\n\nclass MyApp extends React.Component {\n  render() {\n    const request = { hostName: window.location.hostname, path: window.location.pathname };\n    return (\n      <CmsPage componentDefinitions={componentDefinitions} request={request}>\n        { () =>\n          <RenderCmsComponent />\n        }\n      </CmsPage>\n    )\n  }\n}\n```\n\nAt a minimum, `<CmsPage>` and `<RenderCmsComponent>` should be imported.\n\n`<CmsPage>` fetches the Page Model if it is not supplied as a prop (see section on server-side rendering); it fetches \nupdates on component changes in the CMS; and it initializes and manages state, and provides this as context to \n`<RenderCmsComponent>`.\n\n`<RenderCmsComponent>` renders components based on the Page Model API response.\n\nThe `<CmsPage>` component can be put anywhere within a React App. It functions as a higher-order component (HOC). \n`<RenderCmsComponent>` consumes the state from `<CmsPage>` and renders the components and any content referenced from \nthe components as contained in the Page Model API response. The `<RenderCmsComponent>` should be placed in the React app \nat the exact location where you want BloomReach Experience to render its components.\n\nPlease note that `<CmsPage>` takes children as a function instead of as a prop, because it is otherwise not possible to \nprovide state through context providers due to a bug in React currently. So make sure to wrap any children of \n`<CmsPage>` in a function, as in the following example:\n\n ```js\n{ () =>\n  // any children go here\n  <h1>Blooming is what I do</h1>\n}\n ```\n\n`<CmsPage>` takes two props: `componentDefinitions` and `request`.\n\nThe `request` prop is used to fetch the Page Model for the page that is active; and to detect whether preview is active \nso that meta-data for Channel Manager functionality (e.g. in-context editing) is included in the HTML, and consequently \nChannel Manager functionality is enabled.\n\nFinally, component definitions are supplied through the `componentDefinitions` prop. The component definitions tell \n`<RenderCmsComponent>` what React component to render by mapping these to the *hst:label* of a CMS catalog component.\n\n## Server-side rendering\n\nFor server-side rendering (e.g. using [Next.js](https://github.com/zeit/next.js)) you need to fetch the Page Model API \nserver-side and supply it as a prop to `<CmsPage>`. Apart from this the usage is the same as with client-side rendering.\n\nThe helper function `getApiUrl()` can be used to generate the Page Model API URL using the current request.\n\nIt is important to pass cookies from the initial request and supply these with the request header of the Page \nModel API request. Otherwise you will get a 403 error in preview mode.\n\nFinally, to get preview to work for server-side rendered apps you can use a reverse proxy to route requests from \nBloomReach's site preview to the React App-server. For more details, see section *3.2 Server-side apps* of the Hippo Lab: \n[Integrate a React application with BloomReach Experience](https://www.onehippo.org/labs/integrate-a-react-application-with-bloomreach-experience.html).\n\n```js\nimport fetch from 'isomorphic-unfetch'\nimport { getApiUrl, CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\n// setting pageModel to empty list instead of null value,\n// as otherwise the API will be fetched client-side again after server-side fetch errors\nlet pageModel = {}\n\nconst request = { hostname: req.headers.host, path: asPath }\nconst url = getApiUrl(request, {})\n// pass cookies of initial request for CMS preview\nconst response = await fetch(url, {headers: {'Cookie': req.headers.cookie}})\n\nif (response.ok) {\n  try {\n    pageModel = await response.json()\n  } catch (err) {\n    console.log(`Error! Could not convert response to JSON for URL: ${url}`)\n  }\n} else {\n  console.log(`Error! Status code ${response.status} while fetching CMS page data for URL: ${url}`)\n}\n```  \n\n## Example React apps\n\nThere are two example React apps available that use the SDK. One client-side rendered, and one server-side rendered \nusing [Next.js](https://github.com/zeit/next.js). You can find the [example apps on Github](https://github.com/bloomreach/experience-react-sdk/tree/master/examples).\n\n## Creating custom components\n\nAny components that are supplied through the `compenentDefinitions` prop can be any type of valid React component, \nincluding functional components. Props are passed to these components as context so that you can access the components' \nconfiguration, content, etc. See more information below.\n\n### Props\n\nThe following props are passed to a component that is rendered by `<RenderCmsComponent>`:\n- `configuration` - `Object` component configuration. Contains the contributed models, raw parameters and resolved \n parameters. Content included in the component's model is not serialized as part of the component's configuration but in \n a separate content object, and a JSON Pointer reference is used to link to the actual content object. This is done to \n prevent content from being included multiple times in the API response when referenced multiple times. \n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview is active based on current URL supplied through `request` prop of \n`<CmsPage>`.\n\nFor more information on the Page Model API response, see the [Swagger documentation](https://www.onehippo.org/library/concepts/spa-plus/page-model-api/swagger-api-documentation.html).\n\n### Example\n\n```js\nimport React from 'react'\nimport NewsItem from './news-item'\nimport { getNestedObject } from 'bloomreach-experience-react-sdk'\n\nexport default class NewsList extends React.Component {\n  render() {\n    const preview = this.props.preview\n    const pageModel = this.props.pageModel\n    const configuration = this.props.configuration\n\n    // return placeholder if no list is set on component\n    const list = getNestedObject(configuration, ['models', 'pageable', 'items'])\n    if (!list && preview) {\n      return (<p>Click to configure {configuration.label}</p>)\n    } else if (!list) {\n      // don't render placeholder outside of preview mode\n      return null\n    }\n\n    // build list of news articles\n    const listItems = list.map((listItem, index) => {\n      if ('$ref' in listItem) {\n        return (<NewsItem contentRef={listItem.$ref} pageModel={pageModel} preview={preview} key={index}/>)\n      }\n    })\n\n    return (\n      <div className=\"row\">\n        <div className=\"col-sm-12 news-list\">\n          {listItems}\n        </div>\n      </div>\n    )\n  }\n}\n```\n\n### Content components\n\nComponents that reference a single content-item (e.g. the Banner component) can use a convenient wrapper-class that \nlooks up the content and passes it as a prop. See below.\n\nTo enable this, the property `wrapInContentComponent: true` has to be set on the component in the `componentDefinitions` \nprop. See `componentDefinitions` in the API section for more details.\n\n#### Props\n\n- `content` - `Object` raw content object that contains the content-item's fields and field-values. Any references to \n other content-items (e.g. images) are serialized as JSON Pointers.\n- `manageContentButton` - `React.Component` for placement and rendering of the [Manage Content Button](https://www.onehippo.org/library/concepts/component-development/render-manage-content-button.html)\n in preview mode in CMS.\n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview is active based on current URL supplied through `request` prop of \n`<CmsPage>`.\n\n#### Example\n\n```js\nimport React from 'react'\n\nconst content = this.props.content;\nconst manageContentButton = this.props.manageContentButton;\n\nclass Banner extends React.Component {\n  render() {\n    return (\n      <div className=\"my-content-component\">\n        { manageContentButton && manageContentButton }\n        { content.title && content.title }\n      </div>)\n  }\n}\n```\n\n### More component examples\n\nFor more detailed examples, see the components included in the [example applications](https://github.com/bloomreach/experience-react-sdk/tree/master/examples/client-side-rendered/src/components). \n\n### Helper functions\n\nAdditionally, there are a variety of helper functions available. See the examples below. For full details on the APIs, \nsee the API section.\n\n```js\nimport { createLink, getImageUrl, getNestedObject, parseAndRewriteLinks, parseDate } from 'bloomreach-experience-react-sdk'\n\nconst link = createLink('ref', link, linkText, className)\nconst image = getImageUrl(content.image, this.props.pageModel, this.props.preview)\nconst list = getNestedObject(configuration, ['models', 'pageable', 'items', 0])\nconst contentHtml = parseAndRewriteLinks(content.content.value, this.props.preview)\nconst date = parseDate(content.date)\n```\n\n## API\n\n### `<CmsPage>`\n\nThe CmsPage component is a higher-order component that takes care of:\n- Fetching the Page Model for client-side rendering, when not supplied as a prop.\n- Fetching Page Model updates on component changes in the CMS.\n- Initializing and managing state, and providing this as context to `<RenderCmsComponent>`.\n\n#### Properties\n\n- `cmsUrls` - `Object` Override default CMS URL's. (Optional)\n- `componentDefinitions` - `object` Mapping of CMS catalog components to React components. Determines what \ncomponent to render based from the Page Model. (Optional)\n- `createLink` - `Function` Called when creating internal links so that links can be constructed using the router \nlibrary of the React app. (Optional)\n- `pageModel` - `Object` Supply Page Model as prop. Used for server-side-rendering where Page Model API is fetched \nserver-side. When supplied, `CmsPage` will not fetch Page Model API on mount, only on component updates in CMS.\n(Optional)\n- `request` - `String` Current URL-path for determining if preview mode is active, and for fetching the Page Model for \nthe page that is active. (Required)\n\n###### `cmsUrls` property\n\nProperty that allows you to override the default URL's for fetching the Page Model API. Typically you will only have to \ndefine `scheme`, `hostname`, `port`, and `contextPath`. Input object takes the following properties (all are \noptional):\n- `scheme` - `String` scheme (default: *http*)\n- `hostname` - `String` hostname (default: *localhost*)\n- `port` - `number` port number (default: *8080*)\n- `contextPath` - `String` site context-path (default: *site*)\n- `channelPath` - `String` path to the used channel, if channel is accessed through a subpath\n- `previewPrefix` - `String` preview-prefix used by CMS (default: *_cmsinternal*)\n- `apiPath` - `String` path to Page Model API as subpath (default: *resourceapi*)\n- `apiComponentRenderingUrlSuffix` - `String` (default: *?_hn:type=component-rendering&_hn:ref=*)\n\n###### `componentDefinitions` property\n\nMaps CMS catalog components to React components. Expects as input an object with `hst:label` of the CMS components as \nkeys and as value another object. The nested object has the mandatory property `component` who's value maps the CMS \ncomponent to a React component. See the example below:\n\n```js\nconst componentDefinitions = {\n  \"MyCustomCmsComponent\": { component: MyCustomReactComponent },\n  \"AnotherCmsComponent\": { component: AnotherReactComponent, wrapInContentComponent: true }\n};\n```\n\nAdditionally, the property `wrapInContentComponent: true` can be used for components \nthat reference a single content-item. When this property is set on a component, it will be wrapped in a convenient \nwrapper class. See section *Content components*.\n\n##### `createLink` property\n\nCalled when creating internal links so that links can be constructed using the router \nlibrary of the React app. \n\nTakes `Function` as input. The function should return valid JSX and have three parameters:\n- `href` - `String` href of link\n- `linkText` - `Function` contains the HTML that is wrapped inside the link. Is a function so that it can include HTML.\n- `className` - `String` classnames to add to the link element\n\nFor example:\n```js\nconst createLink = (href, linkText, className) => {\n  return (<Link className={className} to={href}>{linkText()}</Link>)\n}\n```\n\n##### `pageModel` property\n\nPage Model can be supplied as a prop when using a server-side rendered / isomorphic React framework. When supplied, \n`<CmsPage>` will not fetch the Page Model API client-side. \n\n##### `request` property\n\nTakes `Object` as input with properties `hostname` and `path`, both of type `String`. The property \n`hostname` should contain the hostname for the current request (client-side this is window.location.hostname). The \nproperty `path` should contain the URL-path for the current request (client-side this is window.location.pathname);\n\n### `<RenderCmsComponent>`\n\nRenders a CMS component and all of its children using the Page Model supplied by `<CmsPage>`. Will render the entire \nPage Model by default.\n\n#### Properties\n\n- `path` - `String` path to a component (static CMS component), container or container-item in the Page Model to render \nonly that component and its children. If no path is supplied, entire Page Model will be rendered. \n\n#### Example\n\n```js\n<RenderCmsComponent path={'main/container/banner'}/>\n```\n\n### `getApiUrl(request, [newCmsUrls])`\n\nHelper function for generating URL to the Page Model API for server-side fetching of the Page Model. \n\n#### Arguments\n\n- `request` - `Object` containing hostname and URL-path as properties `hostname` and `path` respectively. See the \n`request` property section above.\n- `newCmsUrls` - `Object` takes `cmsUrls` property as input to override default CMS URL's\n\n#### Return types\n\n`String` returns URL for fetching Page Model API\n\n### `createLink(linkType, link, linkText, className)`\n\nCreates a link to either a component or content-item itself or a referenced content-item (can be a document, image or \nasset) and returns the link as JSX.  \n\n#### Arguments\n\n- `linkType` - `String` type of link to create. Valid values are `self`, `ref` or `href`.\n  - `self` - Create link to the component or content-item itself. E.g. for a news-item in a news overview.\n  - `ref` - Create link to a referenced content-item. E.g. for a banner.\n  - `href` -  Used by `parseAndRewriteLinks()` to create links using a href only.\n- `link` - `Object` the component configuration or content-object that is linking to itself or referenced another \ncontent-item.\n- `linkText` - `JSX | Function` HTML to wrap inside the link. Is a function so that it can include HTML.\n- `className` - `String` classnames to add to the link element\n\n#### Return types\n\n`JSX` returns link as JSX object that can be included as a variable anywhere within the return section of a React \ncomponent's render method.\n\n### `getImageUrl(imageRef, pageModel, preview)`\n\nCreates link to URL of image in case BloomReach Experience is used for serving images.\n\n#### Arguments\n\n- `imageRef` - `String` JSON Pointer that references the image.\n- `pageModel` - `Object` since this function is a pure JavaScript function it can't get Page Model from context, so it \nhas to be provided as function parameter. The Page Model is used to retrieve the image.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by `<RenderCmsComponent>` can \npass the prop `this.props.preview`.\n\n#### Return types\n\n`String` returns URL to image.\n\n### `getNestedObject(nestedObject, pathArray)`\n\nReturns a nested object or value using a path array. Useful when you need to access deeply nested objects/values without\nhaving to string null checks together.\n\n#### Arguments\n\n- `nestedObject` - `Object` the object containing the nested object or value.\n- `pathArray` - `Array` contains the path to the nested object as an array.\n\n#### Return types\n\n`Object|null` returns the nested object if found, otherwise returns null. \n\n### `parseAndRewriteLinks(html, preview)`\n\nParses HTML of a rich-text field of a content-item for rewriting links in HTML to internal links. Uses the `createLink` \nfunction passed to `<CmsPage>` for constructing internal links.\n\n#### Arguments\n\n- `html` - `String` value of rich-text field of a content-item. Should contain HTML only.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by `<RenderCmsComponent>` can \npass the prop `this.props.preview`.\n\n#### Return types\n\n`JSX` returns parsed and rewrited HTML as JSX.\n\n### `parseDate(date)`\n\nParses date-field of a content item and returns date as a string.\n\n#### Arguments\n\n- `date` - `String` takes raw value of a date-field as input, following the ISO 8601:2000 format.\n\n#### Return types\n\n`String` returns date in full date format.\n\n## Release notes\n\n### Version 0.2.0\n\nThis version includes significant changes. Please make sure to update your components using the upgrade steps further \ndown.\n- Changed `cmsUrls` property to support different live and preview URLs.\n- Changed `urlPath` property to `request` property which no longer takes URL-path as string, but an object with hostname \nand URL-path. This property should be passed to `<CmsPage>`.\n- Changed helper method `getApiUrl()` to take `request` property as parameter instead of `urlPath`.\n- Changed helper method `parseAndRewriteLinks()` to take an extra parameter: `preview`.\n- Changed helper method `getImageUrl()` to take an extra parameter: `preview`.\n\nUpgrade steps:\n- Modify `cmsUrls` property to include URLs for live and preview using the properties `live` and `preview` respectively.\nPlease note that the `cms` prefix has been removed from all URL properties. So `cmsHostname` has become `hostname`. \nPreview URLs are optional. For example:\n  ```js\n  const cmsUrls = {\n    live: {\n      hostname: bloomreach.com\n    },\n    preview: {\n      hostname: cms.bloomreach.com\n    }\n  }\n  ```\n- Pass current request details through `request` property to `<CmsPage>`. This was previously done through the `urlPath` \nproperty. The `request` property should be an object that contains the hostname and path as properties `hostname` and \n`path` respectively. For example:\n  ```js\n  const request = { hostname: window.location.hostname, path: window.location.path };\n  <CmsPage componentDefinitions={componentDefinitions} request={request}>\n  ```\n- Update usage of `getApiUrl` to pass `request` property (see previous bullet) instead of URL-path.\n- Update usage of helper methods `getImageUrl()` and `parseAndRewriteLinks()` to include the preview parameter. \nComponents rendered by `<RenderCmsComponent>` have the preview value passed as prop `this.props.preview`.\n\n## FAQ / Troubleshooting\n\nNothing here yet :)\n\n## Author\n\nRobbert Kauffman - BloomReach\n","gitHead":"2b261a3a2af796f8d5ac53591b7120e8402109a0","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"rkauffman","email":"robbertkauffman@gmail.com"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.2.0","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.8.0","dependencies":{"jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.2.0-rc2_1534954063421_0.24021320548492775","host":"s3://npm-registry-packages"}},"0.2.0":{"name":"bloomreach-experience-react-sdk","version":"0.2.0","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.2.0","maintainers":[{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"d4e88183b88702d5b327cae2368296b4b11476bd","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.2.0.tgz","fileCount":28,"integrity":"sha512-kPXTbPiU1TIZnG7oRoMAqdFOMlBLrkunlplJ+87AuJX8JPYnn0ucuQO3lNGO1DPAXiNNXl+MZEopbVJWtD0KAQ==","signatures":[{"sig":"MEQCIG31tJTRgMgqtaWXvrfZv+KYV+sw4Fy/UY3w+D/3ixFLAiBa0ZeQ89JRHGxOHp8j6daGRdIuXZyezzLwUOUenSaqiQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":238973,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbh/a6CRA9TVsSAnZWagAAhscQAJ5Ms0079BVpfzg343JV\n1+GaRGDuHCTALNrXLI3CGOjoVq7E9iEt0Jifmc3olJP7HS+qcikL8lWzjkvw\nDX0/BpOhTmbP4WJVfIQ1j5rBIVaJrz4YR+iK0CJ2uFnftJX2oqptbuUgtaYg\npqvBHZtVFHw5psw7gq4T9VSf1hcyrb0E4CEJAjGho2kb8U2PBLFU+BhdoMom\nxtQerUIxW0tqx9ueNivEtB+x0p+QjAR92q6bktr4z7whZ8mc4bVj2dDmt1P9\nkvchS1jOY1Uhs/VTlZt+UrGAkyAA3GoMK+Ce0CYa7L/IbGNR8Uc2shPNZYvV\nGYW1cmscgOoY2ifaXWGedi8HuFP/LwncnJwsoRSXpRqyoBntKwrtjq4If8j2\nqQkhAIoKJFe2/5ZtL4ru8u2kf53GLmVpeGFgrGM+tbE1rnQfita6m2hfdpi5\nM4j6lU/EjhwzQctZ+jopyfCOhZNKdjxBqyAbL8j5EAr3OnnZhqaqHIAfwfTa\nQHmBcen/6KdPF5Oyz6wDyjvOPR1jh0yE1/W5s8q+NyFQMv9sqQQbXGwNUpRm\noCGlBjUUkXgvYS7R6UvhJ84AVT7eiMY1uLpH8PyuqntJpQu96eQabjySwh4a\nSx8j3tbtZV5u9CL0jIa2a103xuHBdiUqpDV2ZAyKku2sahDckfqOA/2RklUM\nhL89\r\n=gUMd\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","gitHead":"e6c824afc280b69040a0e2af9b1738e7b7e7aa7d","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"rkauffman","email":"robbertkauffman@gmail.com"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.2.0","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.8.0","dependencies":{"jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.2.0_1535637177702_0.6239076342432803","host":"s3://npm-registry-packages"}},"0.2.1":{"name":"bloomreach-experience-react-sdk","version":"0.2.1","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.2.1","maintainers":[{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"e29d303be79956e55a591071caa66a3d47c4a197","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.2.1.tgz","fileCount":28,"integrity":"sha512-cuZriBcOkwo/FVPnEUWj4Me+av09t8GkVY/+SAyC4uno4yyIXkPFwowmv2O19nKKNe+JExhrpU6HgH/wEWe3CA==","signatures":[{"sig":"MEUCIANQyFmSi7yUqnErhKOIhTP2I1mF459zeZ2NX+p24L1FAiEA5AZuGHP40WtrvhpMggtTIzt69eZxmKzYcefiMTSwLZo=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":239619,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbm7c+CRA9TVsSAnZWagAAToAQAJeY8yVKgNC4JrlZeBfh\n4yY1Ep6OWn+rZnkNW8KwMy3UlGwzqQ3x7ec84zjF8pO6kGQK844AFuojnDq6\n4m97YvW6rrrG7iLM7XGx5//aBukc7tRNLhJ7E/dWo6z16RpBQu+R3z0VApwl\nYjtkb++Ca/kGbbFuhVwdqXVaez8Y0PKm0HlJmHWItHgvyUoVlK80dwDO95hh\nqJ15zOi9Im5CqxFZUdu87rEebhFoyFfhPXTp+iIfpGyE/rHAexD8TumN4I4K\n8AilSUaj5VpDlq0fY1tu5WoM4iwwsJgOOHs+/aHoP/kiR2Lj0FthtES6Ec4l\nyltElyebeypWPKjtMx+pY9B7IC06hMQHRmpWyQOKTdw9Rd7SwyxdoDUp9fhS\ngsxbiZnbN9NbgZQyuxpOr7GB/ycm/D/IZzybtU9CoOFdEPPlO4BrJO+AT0e9\n2WmwuiJoIF3QIZCptlMKIqE7J0T8nk51W9vtRf2MuhiyMxnt9g6/4HoiZwc6\nx5mNSC9ce+XQMSMt84I2G0Wuvqh9L22jOKrrj4um/UBh/HCYSCiiQD0ntUTg\nmsEyjRdtK9lPsZnkEnDy6ZfsFG6NXmTZ1QSreKCk2dsaAQIXxH7CL/yT5fw0\nnEN72V6tTru254LUI5cEHS64i1131liU882pSQGI8ku3z0WaknIkABwzxt2o\na2hL\r\n=KCno\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","gitHead":"4d43ec52a54ac0ee04d631a61ce3f2a1a2623dbd","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"rkauffman","email":"robbertkauffman@gmail.com"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.2.0","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.8.0","dependencies":{"jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.2.1_1536931646031_0.3298008686127101","host":"s3://npm-registry-packages"}},"0.3.0-rc1":{"name":"bloomreach-experience-react-sdk","version":"0.3.0-rc1","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.3.0-rc1","maintainers":[{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"8742e3214d509820fe1b4920824f78d803c57c2d","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.3.0-rc1.tgz","fileCount":28,"integrity":"sha512-FFJHwpSunmDyB6ob2SNDwir4X9Pi15H2Z/5Tn8An0FGCc6fEYOiUOtDhgLif5HXgUYTDiFtMzZ63XCdF210sgA==","signatures":[{"sig":"MEUCIEA4RdhI1TKbh5Opk83rjSxj2wOSivm/LwBhCHTGsYKeAiEA2LCS19XtFRJ1Q8Bq/xymVdOAGQzJPl2OWmO99FD3ZVY=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":240349,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbnCufCRA9TVsSAnZWagAAnM0P/3MqLRdlfZS7/bL3HWhi\np6E44CYhEhO3xCgI5plOCbAm09aMhLVLuuWSk4vDlG2VSK9ofE5017HO31pN\nKSpE8sAOWIqCJWn+g/+Cy3QRcIBO4OiTmws1B14zzqUtdahuY5uoDS96d77x\nUC9bPVbSv5YvsWFyilgNNhwa3fxidzZr9llU4CmcO+hgEDBRO79oh0/I9zBw\nvdh6D/liZUJVpmaP81uhKiXSV7mU5PLuYH2Tqvdn2j/VIsLHMyMuElQiFyS5\nWEt1E+Hwz3RutOcElY47mqOtGS4UCsW4Gxx3w1u07NISwA2cySUsatFkfaag\n0nioNiuo5Qo7enbRFvli6jyLn0FGFB7nWVcG2xsNQSwenPhWUtSUJu3ui8IK\n1AcOBWji7M6w4Olm9JFeR6gVinUIfI7F4DwXlBr9D4zwaD5/viqcDD4KW/xF\npHH/F/DH5W587IiX5bArx5UCpMbbobrRBm8Wckwyi0IFHUaqVxClYmx/vw6R\npBcn7nTgK2gnL7lwGW6O2/6jINtfJ9bWCzAJE9tKGlvJol1Z5DKK/LqGw7IO\nnNhZjCJ3T2PUpQO3AtqpStqZjbb4VLkbF4AzHaHpebUE1hIbhQ2p4pExl2oD\n7itsOM5kZOR/wrH7LKpNrkO+Vop6fn4cGy+t4J+e5laHTptmmy0hxc19oOM2\nW+GO\r\n=PX91\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","readme":"# BloomReach Experience SDK for React\n\nSDK for powering content and components in React applications by [BloomReach Experience](https://www.bloomreach.com/en/products/experience). \nThis library makes integrating a React app with BloomReach Experience a breeze. It supports both client-side- and \nserver-side rendered/isomorphic React apps. \n\nBloomReach Experience allows you to use an external front-end such as React for rendering while still providing a \nnative-like authoring experience, such as integrated preview, in-context editing, drag & drop, server-side \npersonalization. For more information on this approach, see [A new approach to integrating SPA's with WCM: Fixing what's \nwrong with headless integrations](https://www.bloomreach.com/en/blog/2018/03/a-new-approach-to-integrating-spas-with-wcm-fixing-what%E2%80%99s-wrong-with-headless-integrations.html).\n\n## Install\n\n```bash\nnpm install bloomreach-experience-react-sdk --save\n```\n\n## Usage\n\n```js\nimport React from 'react'\nimport { CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\nconst componentDefinitions = {\n  \"MyCustomComponent\": { component: MyCustomComponent }\n}\n\nclass MyApp extends React.Component {\n  render() {\n    const request = { hostname: window.location.hostname, path: window.location.pathname };\n    return (\n      <CmsPage componentDefinitions={componentDefinitions} request={request}>\n        { () =>\n          <RenderCmsComponent />\n        }\n      </CmsPage>\n    )\n  }\n}\n```\n\nAt a minimum, `<CmsPage>` and `<RenderCmsComponent>` should be imported.\n\n`<CmsPage>` fetches the Page Model if it is not supplied as a prop (see section on server-side rendering); it fetches \nupdates on component changes in the CMS; and it initializes and manages state, and provides this as context to \n`<RenderCmsComponent>`.\n\n`<RenderCmsComponent>` renders components based on the Page Model API response.\n\nThe `<CmsPage>` component can be put anywhere within a React App. It functions as a higher-order component (HOC). \n`<RenderCmsComponent>` consumes the state from `<CmsPage>` and renders the components and any content referenced from \nthe components as contained in the Page Model API response. The `<RenderCmsComponent>` should be placed in the React app \nat the exact location where you want BloomReach Experience to render its components.\n\nPlease note that `<CmsPage>` takes children as a function instead of as a prop, because it is otherwise not possible to \nprovide state through context providers due to a bug in React currently. So make sure to wrap any children of \n`<CmsPage>` in a function, as in the following example:\n\n ```js\n{ () =>\n  // any children go here\n  <h1>Blooming is what I do</h1>\n}\n ```\n\n`<CmsPage>` takes two props: `componentDefinitions` and `request`.\n\nThe `request` prop is used to fetch the Page Model for the page that is active; and to detect whether preview is active \nso that meta-data for Channel Manager functionality (e.g. in-context editing) is included in the HTML, and consequently \nChannel Manager functionality is enabled.\n\nFinally, component definitions are supplied through the `componentDefinitions` prop. The component definitions tell \n`<RenderCmsComponent>` what React component to render by mapping these to the *hst:label* of a CMS catalog component.\n\n## Server-side rendering\n\nFor server-side rendering (e.g. using [Next.js](https://github.com/zeit/next.js)) you need to fetch the Page Model API \nserver-side and supply it as a prop to `<CmsPage>`. Apart from this the usage is the same as with client-side rendering.\n\nThe helper function `getApiUrl()` can be used to generate the Page Model API URL using the current request.\n\nIt is important to pass cookies from the initial request and supply these with the request header of the Page \nModel API request. Otherwise you will get a 403 error in preview mode.\n\nFinally, to get preview to work for server-side rendered apps you can use a reverse proxy to route requests from \nBloomReach's site preview to the React App-server. For more details, see section *3.2 Server-side apps* of the Hippo Lab: \n[Integrate a React application with BloomReach Experience](https://www.onehippo.org/labs/integrate-a-react-application-with-bloomreach-experience.html).\n\n```js\nimport fetch from 'isomorphic-unfetch'\nimport { getApiUrl, CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\n// setting pageModel to empty list instead of null value,\n// as otherwise the API will be fetched client-side again after server-side fetch errors\nlet pageModel = {}\n\nconst request = { hostname: req.headers.host, path: asPath }\nconst url = getApiUrl(request, {})\n// pass cookies of initial request for CMS preview\nconst response = await fetch(url, {headers: {'Cookie': req.headers.cookie}})\n\nif (response.ok) {\n  try {\n    pageModel = await response.json()\n  } catch (err) {\n    console.log(`Error! Could not convert response to JSON for URL: ${url}`)\n  }\n} else {\n  console.log(`Error! Status code ${response.status} while fetching CMS page data for URL: ${url}`)\n}\n```  \n\n## Example React apps\n\nThere are two example React apps available that use the SDK. One client-side rendered, and one server-side rendered \nusing [Next.js](https://github.com/zeit/next.js). You can find the [example apps on Github](https://github.com/bloomreach/experience-react-sdk/tree/master/examples).\n\n## Creating custom components\n\nAny components that are supplied through the `compenentDefinitions` prop can be any type of valid React component, \nincluding functional components. Props are passed to these components as context so that you can access the components' \nconfiguration, content, etc. See more information below.\n\n### Props\n\nThe following props are passed to a component that is rendered by `<RenderCmsComponent>`:\n- `configuration` - `Object` component configuration. Contains the contributed models, raw parameters and resolved \n parameters. Content included in the component's model is not serialized as part of the component's configuration but in \n a separate content object, and a JSON Pointer reference is used to link to the actual content object. This is done to \n prevent content from being included multiple times in the API response when referenced multiple times. \n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview is active based on current URL supplied through `request` prop of \n`<CmsPage>`.\n\nFor more information on the Page Model API response, see the [Swagger documentation](https://www.onehippo.org/library/concepts/spa-plus/page-model-api/swagger-api-documentation.html).\n\n### Example\n\n```js\nimport React from 'react'\nimport NewsItem from './news-item'\nimport { getNestedObject } from 'bloomreach-experience-react-sdk'\n\nexport default class NewsList extends React.Component {\n  render() {\n    const preview = this.props.preview\n    const pageModel = this.props.pageModel\n    const configuration = this.props.configuration\n\n    // return placeholder if no list is set on component\n    const list = getNestedObject(configuration, ['models', 'pageable', 'items'])\n    if (!list && preview) {\n      return (<p>Click to configure {configuration.label}</p>)\n    } else if (!list) {\n      // don't render placeholder outside of preview mode\n      return null\n    }\n\n    // build list of news articles\n    const listItems = list.map((listItem, index) => {\n      if ('$ref' in listItem) {\n        return (<NewsItem contentRef={listItem.$ref} pageModel={pageModel} preview={preview} key={index}/>)\n      }\n    })\n\n    return (\n      <div className=\"row\">\n        <div className=\"col-sm-12 news-list\">\n          {listItems}\n        </div>\n      </div>\n    )\n  }\n}\n```\n\n### Content components\n\nComponents that reference a single content-item (e.g. the Banner component) can use a convenient wrapper-class that \nlooks up the content and passes it as a prop. See below.\n\nTo enable this, the property `wrapInContentComponent: true` has to be set on the component in the `componentDefinitions` \nprop. See `componentDefinitions` in the API section for more details.\n\n#### Props\n\n- `content` - `Object` raw content object that contains the content-item's fields and field-values. Any references to \n other content-items (e.g. images) are serialized as JSON Pointers.\n- `manageContentButton` - `React.Component` for placement and rendering of the [Manage Content Button](https://www.onehippo.org/library/concepts/component-development/render-manage-content-button.html)\n in preview mode in CMS.\n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview is active based on current URL supplied through `request` prop of \n`<CmsPage>`.\n\n#### Example\n\n```js\nimport React from 'react'\n\nconst content = this.props.content;\nconst manageContentButton = this.props.manageContentButton;\n\nclass Banner extends React.Component {\n  render() {\n    return (\n      <div className=\"my-content-component\">\n        { manageContentButton && manageContentButton }\n        { content.title && content.title }\n      </div>)\n  }\n}\n```\n\n### More component examples\n\nFor more detailed examples, see the components included in the [example applications](https://github.com/bloomreach/experience-react-sdk/tree/master/examples/client-side-rendered/src/components). \n\n### Helper functions\n\nAdditionally, there are a variety of helper functions available. See the examples below. For full details on the APIs, \nsee the API section.\n\n```js\nimport { createLink, getImageUrl, getNestedObject, parseAndRewriteLinks, parseDate } from 'bloomreach-experience-react-sdk'\n\nconst link = createLink('ref', link, linkText, className)\nconst image = getImageUrl(content.image, this.props.pageModel, this.props.preview)\nconst list = getNestedObject(configuration, ['models', 'pageable', 'items', 0])\nconst contentHtml = parseAndRewriteLinks(content.content.value, this.props.preview)\nconst date = parseDate(content.date)\n```\n\n## API\n\n### `<CmsPage>`\n\nThe CmsPage component is a higher-order component that takes care of:\n- Fetching the Page Model for client-side rendering, when not supplied as a prop.\n- Fetching Page Model updates on component changes in the CMS.\n- Initializing and managing state, and providing this as context to `<RenderCmsComponent>`.\n\n#### Properties\n\n- `cmsUrls` - `Object` Override default CMS URL's. (Optional)\n- `componentDefinitions` - `object` Mapping of CMS catalog components to React components. Determines what \ncomponent to render based from the Page Model. (Optional)\n- `createLink` - `Function` Called when creating internal links so that links can be constructed using the router \nlibrary of the React app. (Optional)\n- `pageModel` - `Object` Supply Page Model as prop. Used for server-side-rendering where Page Model API is fetched \nserver-side. When supplied, `CmsPage` will not fetch Page Model API on mount, only on component updates in CMS.\n(Optional)\n- `request` - `String` Current URL-path for determining if preview mode is active, and for fetching the Page Model for \nthe page that is active. (Required)\n\n###### `cmsUrls` property\n\nProperty that allows you to override the default URL's for fetching the Page Model API. Typically you will only have to \ndefine `scheme`, `hostname`, `port`, and `contextPath`. Input object takes the following properties (all are \noptional):\n- `scheme` - `String` scheme (default: *http*)\n- `hostname` - `String` hostname (default: *localhost*)\n- `port` - `number` port number (default: *8080*)\n- `contextPath` - `String` site context-path (default: *site*)\n- `channelPath` - `String` path to the used channel, if channel is accessed through a subpath\n- `previewPrefix` - `String` preview-prefix used by CMS (default: *_cmsinternal*)\n- `apiPath` - `String` path to Page Model API as subpath (default: *resourceapi*)\n- `apiComponentRenderingUrlSuffix` - `String` (default: *?_hn:type=component-rendering&_hn:ref=*)\n\n###### `componentDefinitions` property\n\nMaps CMS catalog components to React components. Expects as input an object with `hst:label` of the CMS components as \nkeys and as value another object. The nested object has the mandatory property `component` who's value maps the CMS \ncomponent to a React component. See the example below:\n\n```js\nconst componentDefinitions = {\n  \"MyCustomCmsComponent\": { component: MyCustomReactComponent },\n  \"AnotherCmsComponent\": { component: AnotherReactComponent, wrapInContentComponent: true }\n};\n```\n\nAdditionally, the property `wrapInContentComponent: true` can be used for components \nthat reference a single content-item. When this property is set on a component, it will be wrapped in a convenient \nwrapper class. See section *Content components*.\n\n##### `createLink` property\n\nCalled when creating internal links so that links can be constructed using the router \nlibrary of the React app. \n\nTakes `Function` as input. The function should return valid JSX and have three parameters:\n- `href` - `String` href of link\n- `linkText` - `Function` contains the HTML that is wrapped inside the link. Is a function so that it can include HTML.\n- `className` - `String` classnames to add to the link element\n\nFor example:\n```js\nconst createLink = (href, linkText, className) => {\n  return (<Link className={className} to={href}>{linkText()}</Link>)\n}\n```\n\n##### `pageModel` property\n\nPage Model can be supplied as a prop when using a server-side rendered / isomorphic React framework. When supplied, \n`<CmsPage>` will not fetch the Page Model API client-side. \n\n##### `request` property\n\nTakes `Object` as input with properties `hostname` and `path`, both of type `String`. The property \n`hostname` should contain the hostname for the current request (client-side this is window.location.hostname). The \nproperty `path` should contain the URL-path for the current request (client-side this is window.location.pathname);\n\n### `<RenderCmsComponent>`\n\nRenders a CMS component and all of its children using the Page Model supplied by `<CmsPage>`. Will render the entire \nPage Model by default.\n\n#### Properties\n\n- `path` - `String` path to a component (static CMS component), container or container-item in the Page Model to render \nonly that component and its children. If no path is supplied, entire Page Model will be rendered. \n\n#### Example\n\n```js\n<RenderCmsComponent path={'main/container/banner'}/>\n```\n\n### `getApiUrl(request, [newCmsUrls])`\n\nHelper function for generating URL to the Page Model API for server-side fetching of the Page Model. \n\n#### Arguments\n\n- `request` - `Object` containing hostname and URL-path as properties `hostname` and `path` respectively. See the \n`request` property section above.\n- `newCmsUrls` - `Object` takes `cmsUrls` property as input to override default CMS URL's\n\n#### Return types\n\n`String` returns URL for fetching Page Model API\n\n### `createLink(linkType, link, linkText, className)`\n\nCreates a link to either a component or content-item itself or a referenced content-item (can be a document, image or \nasset) and returns the link as JSX.  \n\n#### Arguments\n\n- `linkType` - `String` type of link to create. Valid values are `self`, `ref` or `href`.\n  - `self` - Create link to the component or content-item itself. E.g. for a news-item in a news overview.\n  - `ref` - Create link to a referenced content-item. E.g. for a banner.\n  - `href` -  Used by `parseAndRewriteLinks()` to create links using a href only.\n- `link` - `Object` the component configuration or content-object that is linking to itself or referenced another \ncontent-item.\n- `linkText` - `JSX | Function` HTML to wrap inside the link. Is a function so that it can include HTML.\n- `className` - `String` classnames to add to the link element\n\n#### Return types\n\n`JSX` returns link as JSX object that can be included as a variable anywhere within the return section of a React \ncomponent's render method.\n\n### `getImageUrl(imageRef, pageModel, preview)`\n\nCreates link to URL of image in case BloomReach Experience is used for serving images.\n\n#### Arguments\n\n- `imageRef` - `String` JSON Pointer that references the image.\n- `pageModel` - `Object` since this function is a pure JavaScript function it can't get Page Model from context, so it \nhas to be provided as function parameter. The Page Model is used to retrieve the image.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by `<RenderCmsComponent>` can \npass the prop `this.props.preview`.\n\n#### Return types\n\n`String` returns URL to image.\n\n### `getNestedObject(nestedObject, pathArray)`\n\nReturns a nested object or value using a path array. Useful when you need to access deeply nested objects/values without\nhaving to string null checks together.\n\n#### Arguments\n\n- `nestedObject` - `Object` the object containing the nested object or value.\n- `pathArray` - `Array` contains the path to the nested object as an array.\n\n#### Return types\n\n`Object|null` returns the nested object if found, otherwise returns null. \n\n### `parseAndRewriteLinks(html, preview)`\n\nParses HTML of a rich-text field of a content-item for rewriting links in HTML to internal links. Uses the `createLink` \nfunction passed to `<CmsPage>` for constructing internal links.\n\n#### Arguments\n\n- `html` - `String` value of rich-text field of a content-item. Should contain HTML only.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by `<RenderCmsComponent>` can \npass the prop `this.props.preview`.\n\n#### Return types\n\n`JSX` returns parsed and rewrited HTML as JSX.\n\n### `parseDate(date)`\n\nParses date-field of a content item and returns date as a string.\n\n#### Arguments\n\n- `date` - `String` takes raw value of a date-field as input, following the ISO 8601:2000 format.\n\n#### Return types\n\n`String` returns date in full date format.\n\n## Release notes\n\n### Version 0.2.0\n\nThis version includes significant changes. Please make sure to update your components using the upgrade steps further \ndown.\n- Changed `cmsUrls` property to support different live and preview URLs.\n- Changed `urlPath` property to `request` property which no longer takes URL-path as string, but an object with hostname \nand URL-path. This property should be passed to `<CmsPage>`.\n- Changed helper method `getApiUrl()` to take `request` property as parameter instead of `urlPath`.\n- Changed helper method `parseAndRewriteLinks()` to take an extra parameter: `preview`.\n- Changed helper method `getImageUrl()` to take an extra parameter: `preview`.\n\nUpgrade steps:\n- Modify `cmsUrls` property to include URLs for live and preview using the properties `live` and `preview` respectively.\nPlease note that the `cms` prefix has been removed from all URL properties. So `cmsHostname` has become `hostname`. \nPreview URLs are optional. For example:\n  ```js\n  const cmsUrls = {\n    live: {\n      hostname: bloomreach.com\n    },\n    preview: {\n      hostname: cms.bloomreach.com\n    }\n  }\n  ```\n- Pass current request details through `request` property to `<CmsPage>`. This was previously done through the `urlPath` \nproperty. The `request` property should be an object that contains the hostname and path as properties `hostname` and \n`path` respectively. For example:\n  ```js\n  const request = { hostname: window.location.hostname, path: window.location.path };\n  <CmsPage componentDefinitions={componentDefinitions} request={request}>\n  ```\n- Update usage of `getApiUrl` to pass `request` property (see previous bullet) instead of URL-path.\n- Update usage of helper methods `getImageUrl()` and `parseAndRewriteLinks()` to include the preview parameter. \nComponents rendered by `<RenderCmsComponent>` have the preview value passed as prop `this.props.preview`.\n\n## FAQ / Troubleshooting\n\nNothing here yet :)\n\n## Author\n\nRobbert Kauffman - BloomReach\n","gitHead":"8ab8111d70cb04883a45314dc2525e510c976d83","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"rkauffman","email":"robbertkauffman@gmail.com"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.2.0","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.8.0","dependencies":{"jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.3.0-rc1_1536961438796_0.9885615814030346","host":"s3://npm-registry-packages"}},"0.4.0-rc1":{"name":"bloomreach-experience-react-sdk","version":"0.4.0-rc1","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.4.0-rc1","maintainers":[{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"b7a153f17dd5508b420d971f669406618392c927","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.4.0-rc1.tgz","fileCount":27,"integrity":"sha512-tCh7UJzKZCCFgZbgJRIl7AWRdRKjReoLJ37uBYUgiIgfi2D1HFthmwye1ZAbp76kwkgvJ9bKHZA/ch1hRfwE4A==","signatures":[{"sig":"MEYCIQC09kThbNyeeG+nqzPvz84jmeYhCiEGEAwdOftH77KVsgIhAN8OUrN0LKfEu79DxoePYpexXTywjF7ZS4UDjS1wI7HP","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":239605,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbnscsCRA9TVsSAnZWagAAulsP/2WxoV0TCdu07jtxOr4w\nogr7OqGHMEpOHBEfUDv0XsNIFwqpsEL2pdxc90nSkPF7fO5pTlhma3n1XZd+\nLaZhibwbbBXU0i09Qf78/M+CncZndL15HcpFD1gAYeGpoiV3ygkp57EJSgRj\na2YBNGpWZEAE5BpLN36fLkXhmsBwpCiJsbMl4R6+vI5u9TkfSvoBtek5WxS/\nFTCCc5h+Ud3yiAbYrfYANRBWLG9mACGergqmXGXs5e3IRhn50lkWwQeng63g\nerXKo0LAdaq9RyZsj+FhFlmNlQ11zEa6SLGnl3d4SyV+CXEvD8aqjOS8cZ94\n7qsoWde/Hlbod+g4WeZVKNm54d71DthVRqMDVZPxXlEZDK5hSESjqZ++thvF\nxxyYE3ZOVKRrdW7FKZJ+82XeHJCkXGeZ9v8jg4ZIgpWf714VDrhNbMWPOAXw\nCdLO45MalGdGn6yR9hfLLgO+rKow+qMN69/f3/4LYTnBbdKYA0n/43kGoRp0\ns/T5/Er99M4vSgVAYlrquuUClcIJcIxpniiA942RDHwsigpmh2wR++7f2Zmm\nTs8dF7BX7ERcEjmYwbyUpHKlgusIElfHIuxCYhbck21w8A0gfnlUFZkFA4VJ\nzohqlIP+yoRJtJp8x4IiR3+1nh12OnULvJd3ly3ABZXBIBvfAN9PAnboCdEH\njy5T\r\n=klCz\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","readme":"# BloomReach Experience SDK for React\n\nSDK for powering content and components in React applications by [BloomReach Experience](https://www.bloomreach.com/en/products/experience). \nThis library makes integrating a React app with BloomReach Experience a breeze. It supports both \nclient-side- and server-side rendered/isomorphic React apps. \n\nBloomReach Experience allows you to use an external front-end such as React for rendering while still \nproviding a native-like authoring experience, such as integrated preview, in-context editing, drag & \ndrop, server-side personalization. For more information on this approach, see [A new approach to \nintegrating SPA's with WCM: Fixing what's wrong with headless integrations](https://www.bloomreach.com/en/blog/2018/03/a-new-approach-to-integrating-spas-with-wcm-fixing-what%E2%80%99s-wrong-with-headless-integrations.html).\n\n## Install\n\n```bash\nnpm install --save bloomreach-experience-react-sdk\n```\n\n## Usage\n\n```jsx\nimport React from 'react'\nimport { CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\nconst componentDefinitions = {\n  \"MyCustomComponent\": { component: MyCustomComponent }\n}\n\nclass MyApp extends React.Component {\n  render() {\n    const request = { hostname: window.location.hostname, path: window.location.pathname };\n    return (\n      <CmsPage componentDefinitions={componentDefinitions} request={request}>\n        { () =>\n          <RenderCmsComponent />\n        }\n      </CmsPage>\n    )\n  }\n}\n```\n\nAt a minimum, `<CmsPage>` and `<RenderCmsComponent>` should be imported in the React app.\n\n`<CmsPage>` fetches the Page Model when it is not supplied as a prop (see section on server-side \nrendering); it fetches updates to the page model on component changes in the CMS; and it initializes and \nmanages state, and provides this as context to `<RenderCmsComponent>`. The `<CmsPage>` component can be \nput anywhere within the React App.\n\n`<RenderCmsComponent>` renders components based on the Page Model API response. It consumes the state \nfrom `<CmsPage>` and renders the container components and any content referenced from the components as \ncontained in the Page Model API response. The `<RenderCmsComponent>` should be nested within `<CmsPage>` \nand placed in the React app at the exact location where you want BloomReach Experience to control what \ncomponents and content is rendered.\n\nPlease note that `<CmsPage>` takes children as a function instead of as a prop, because it is not \npossible to provide state through context providers due to a bug in React currently. So make sure to \nwrap any children of `<CmsPage>` in a function, as in the following example:\n\n ```jsx\n{ () =>\n  // any children go here\n  <h1>Blooming is what I do</h1>\n}\n ```\n\n`<CmsPage>` takes two props: `componentDefinitions` and `request`.\n\nThe `request` prop is used to fetch the Page Model for the current page; and to detect whether \npreview mode is active so that meta-data for Channel Manager functionality (e.g. in-context editing) is \nincluded in the HTML, and consequently Channel Manager functionality is enabled.\n\nFinally, component definitions are supplied through the `componentDefinitions` prop. The component \ndefinitions tell `<RenderCmsComponent>` what React component to render by mapping these to the \n*hst:label* of a CMS catalog component.\n\n## Server-side rendering\n\nFor server-side rendering (e.g. using [Next.js](https://github.com/zeit/next.js)) you need to fetch the \nPage Model API server-side and supply it as a prop to `<CmsPage>`. Apart from this the usage is the same \nas with client-side rendering.\n\nThe helper function `getApiUrl()` can be used to generate the Page Model API URL using the current \nrequest.\n\nIt is important to pass cookies from the initial request and supply these with the request header of the \nPage Model API request. Otherwise you will get a 403 error in preview mode.\n\nFinally, to get preview to work for server-side rendered apps you can use a reverse proxy to route \nrequests from BloomReach's site preview to the React App-server. For more details, see section *3.2 \nServer-side apps* of the Hippo Lab: [Integrate a React application with BloomReach Experience](https://www.onehippo.org/labs/integrate-a-react-application-with-bloomreach-experience.html).\n\n```jsx\nimport fetch from 'isomorphic-unfetch'\nimport { getApiUrl, CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\n// setting pageModel to empty list instead of null value,\n// as otherwise the API will be fetched client-side again after server-side fetch errors\nlet pageModel = {}\n\nconst request = { hostname: req.headers.host, path: asPath }\nconst url = getApiUrl(request, {})\n// pass cookies of initial request for CMS preview\nconst response = await fetch(url, {headers: {'Cookie': req.headers.cookie}})\n\nif (response.ok) {\n  try {\n    pageModel = await response.json()\n  } catch (err) {\n    console.log(`Error! Could not convert response to JSON for URL: ${url}`)\n  }\n} else {\n  console.log(`Error! Status code ${response.status} while fetching CMS page data for URL: ${url}`)\n}\n```  \n\n## Example React apps\n\nThere are two example React apps available that use the SDK. One client-side rendered, and one \nserver-side rendered using [Next.js](https://github.com/zeit/next.js). You can find the [example apps on \nGithub](https://github.com/bloomreach/experience-react-sdk/tree/master/examples).\n\n## Creating custom components\n\nAny components that are supplied through the `compenentDefinitions` prop can be any type of valid React \ncomponent, including functional components. Props are passed to these components as context so that you \ncan access the components' configuration, content, etc. See more information below.\n\n### Props\n\nThe following props are passed to a component that is rendered by `<RenderCmsComponent>`:\n- `configuration` - `Object` component configuration. Contains the contributed models, raw parameters \n and resolved parameters. Content included in the component's model is not serialized as part of the \n component's configuration but in a separate content object, and a JSON Pointer reference is used to \n link to the actual content object. This is done to prevent content from being included multiple times \n in the API response when referenced multiple times on a page. \n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview mode is active based on current URL supplied through \n `request` prop of `<CmsPage>`.\n\nFor more information on the Page Model API response, see the [Swagger documentation](https://www.onehippo.org/library/concepts/spa-plus/page-model-api/swagger-api-documentation.html).\n\n### Example\n\n```jsx\nimport React from 'react'\nimport NewsItem from './news-item'\nimport { getNestedObject } from 'bloomreach-experience-react-sdk'\n\nexport default class NewsList extends React.Component {\n  render() {\n    const preview = this.props.preview\n    const pageModel = this.props.pageModel\n    const configuration = this.props.configuration\n\n    // return placeholder if no list is set on component\n    const list = getNestedObject(configuration, ['models', 'pageable', 'items'])\n    if (!list && preview) {\n      return (<p>Click to configure {configuration.label}</p>)\n    } else if (!list) {\n      // don't render placeholder outside of preview mode\n      return null\n    }\n\n    // build list of news articles\n    const listItems = list.map((listItem, index) => {\n      if ('$ref' in listItem) {\n        return (<NewsItem contentRef={listItem.$ref} pageModel={pageModel} preview={preview} key={index}/>)\n      }\n    })\n\n    return (\n      <div className=\"row\">\n        <div className=\"col-sm-12 news-list\">\n          {listItems}\n        </div>\n      </div>\n    )\n  }\n}\n```\n\n### Content components\n\nComponents that reference a single content-item (e.g. the Banner component) can use a convenient \nwrapper-class that looks up the content and passes it as a prop. See below.\n\nTo enable this, the property `wrapInContentComponent: true` has to be set on the component in the \n`componentDefinitions` prop. See `componentDefinitions` in the API section for more details.\n\n#### Props\n\n- `content` - `Object` raw content object that contains the content-item's fields and field-values. Any \n references to other content-items (e.g. images) are serialized as JSON Pointers.\n- `manageContentButton` - `React.Component` for placement and rendering of the [Manage Content Button](https://www.onehippo.org/library/concepts/component-development/render-manage-content-button.html)\n in preview mode in CMS.\n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview is active based on current URL supplied through `request` \n prop of `<CmsPage>`.\n\n#### Example\n\n```jsx\nimport React from 'react'\n\nconst content = this.props.content;\nconst manageContentButton = this.props.manageContentButton;\n\nclass Banner extends React.Component {\n  render() {\n    return (\n      <div className=\"my-content-component\">\n        { manageContentButton && manageContentButton }\n        { content.title && content.title }\n      </div>)\n  }\n}\n```\n\n### Static CMS components\n\nStatic CMS components are components that are defined by developers / administrators and cannot be  \nmodified by users in the CMS. However, any content or site menus these components reference can be \nchanged by users in the CMS.\n\nSince `<RenderCmsComponent>` only renders container components (drag-and-drop components) by default, \nyou have to specify two additional properties in order to render a static CMS component: the `path` \nproperty to point to the relative path of the component, and `renderComponent` to specify which React \ncomponent to use for rendering the component. See the example below.\n\n```jsx\n<RenderCmsComponent path={'menu'} renderComponent={CmsMenu} />\n```\n\n### More component examples\n\nFor more detailed examples, see the components included in the [example applications](https://github.com/bloomreach/experience-react-sdk/tree/master/examples/client-side-rendered/src/components). \n\n### Helper functions\n\nAdditionally, there are a variety of helper functions available. See the examples below. For full \ndetails on the APIs, see the API section.\n\n```jsx\nimport { createLink, getImageUrl, getNestedObject, parseAndRewriteLinks, parseDate } from 'bloomreach-experience-react-sdk'\n\nconst link = createLink('ref', link, linkText, className)\nconst image = getImageUrl(content.image, this.props.pageModel, this.props.preview)\nconst list = getNestedObject(configuration, ['models', 'pageable', 'items', 0])\nconst contentHtml = parseAndRewriteLinks(content.content.value, this.props.preview)\nconst date = parseDate(content.date)\n```\n\n## API\n\n### `<CmsPage>`\n\nThe CmsPage component is a higher-order component that takes care of:\n- Fetching the Page Model for client-side rendering, when not supplied as a prop.\n- Fetching Page Model updates on component changes in the CMS.\n- Initializing and managing state, and providing this as context to `<RenderCmsComponent>`.\n\n#### Properties\n\n- `cmsUrls` - `Object` Override default CMS URL's. (Optional)\n- `componentDefinitions` - `object` Mapping of CMS catalog components to React components. Determines \n what component to render based from the Page Model. (Optional)\n- `createLink` - `Function` Called when creating internal links so that links can be constructed using \n the router library of the React app. (Optional)\n- `pageModel` - `Object` Supply Page Model as prop. Used for server-side-rendering where Page Model API \n is fetched server-side. When supplied, `CmsPage` will not fetch Page Model API on mount, only on \n component updates in CMS. (Optional)\n- `request` - `String` Current URL-path for determining if preview mode is active, and for fetching the \n Page Model for the page that is active. (Required)\n\n###### `cmsUrls` property\n\nProperty that allows you to override the default URL's for fetching the Page Model API. Typically you \nwill only have to define `scheme`, `hostname`, `port`, and `contextPath`. Input object takes the \nfollowing properties (all are optional):\n- `scheme` - `String` scheme (default: *http*)\n- `hostname` - `String` hostname (default: *localhost*)\n- `port` - `number` port number (default: *8080*)\n- `contextPath` - `String` site context-path (default: *site*)\n- `channelPath` - `String` path to the used channel, if channel is accessed through a subpath\n- `previewPrefix` - `String` preview-prefix used by CMS (default: *_cmsinternal*)\n- `apiPath` - `String` path to Page Model API as subpath (default: *resourceapi*)\n- `apiComponentRenderingUrlSuffix` - `String` (default: *?_hn:type=component-rendering&_hn:ref=*)\n\n###### `componentDefinitions` property\n\nMaps CMS catalog components to React components. Expects as input an object with `hst:label` of the CMS \ncomponents as keys and as value another object. The nested object has the mandatory property `component` \nwho's value maps the CMS component to a React component. See the example below:\n\n```js\nconst componentDefinitions = {\n  \"MyCustomCmsComponent\": { component: MyCustomReactComponent },\n  \"AnotherCmsComponent\": { component: AnotherReactComponent, wrapInContentComponent: true }\n};\n```\n\nAdditionally, the property `wrapInContentComponent: true` can be used for components that reference a \nsingle content-item. When this property is set on a component, it will be wrapped in a convenient \nwrapper class. See section *Content components*.\n\n##### `createLink` property\n\nCalled when creating internal links so that links can be constructed using the router library of the \nReact app. \n\nTakes `Function` as input. The function should return valid JSX and have three parameters:\n- `href` - `String` href of link\n- `linkText` - `Function` contains the HTML that is wrapped inside the link. Is a function so that it \n can include HTML.\n- `className` - `String` classnames to add to the link element\n\nFor example:\n```jsx\nconst createLink = (href, linkText, className) => {\n  return (<Link className={className} to={href}>{linkText()}</Link>)\n}\n```\n\n##### `pageModel` property\n\nPage Model can be supplied as a prop when using a server-side rendered / isomorphic React framework. \nWhen supplied, `<CmsPage>` will not fetch the Page Model API client-side. \n\n##### `request` property\n\nTakes `Object` as input with properties `hostname` and `path`, both of type `String`. The property \n`hostname` should contain the hostname for the current request (client-side this is \nwindow.location.hostname). The property `path` should contain the URL-path for the current request \n(client-side this is window.location.pathname);\n\n### `<RenderCmsComponent>`\n\nRenders a CMS component and all of its children using the Page Model supplied by `<CmsPage>`. Will \nrender the entire Page Model by default.\n\n#### Properties\n\n- `path` - `String` path to a component (static CMS component), container or container-item in the Page \n Model to render only that component and its children. If no path is supplied, entire Page Model will be \n rendered. \n- `renderComponent` - `React.Component` render a static CMS component using specified React component. \n Only works in combination with `path` property, which should specify path to the static CMS component. \n Site menus that are rendered this way can leverage the `<CmsEditButton>` component for rendering edit \n buttons in the CMS.\n\n#### Example\n\n```jsx\n<RenderCmsComponent path={'menu'} renderComponent={CmsMenu} />\n```\n\n### `<CmsEditButton>`\n\nInserts meta-data for either a content-item or site menu for placing an edit button in preview mode in \nthe CMS. Content-items that are rendered by a content component using `wrapInContentComponent: true` do \nnot need to use this component, but should use the `manageContentButton` prop that passes the meta-data.\n\n#### Properties\n\n- `configuration` - `Object` configuration of the site menu (not the component configuration containing \nthe menu) or the content-item object which has the `_meta` object in its root.\n- `preview` - `Boolean` toggle to prevent edit buttons from being rendered outside of preview.\n\n### `getApiUrl(request, [newCmsUrls])`\n\nHelper function for generating URL to the Page Model API for server-side fetching of the Page Model. \n\n#### Arguments\n\n- `request` - `Object` containing hostname and URL-path as properties `hostname` and `path` \n respectively. See the `request` property section above.\n- `newCmsUrls` - `Object` takes `cmsUrls` property as input to override default CMS URL's\n\n#### Return types\n\n`String` returns URL for fetching Page Model API\n\n### `createLink(linkType, link, linkText, className)`\n\nCreates a link to either a component or content-item itself or a referenced content-item (can be a \ndocument, image or asset) and returns the link as JSX.  \n\n#### Arguments\n\n- `linkType` - `String` type of link to create. Valid values are `self`, `ref` or `href`.\n  - `self` - Create link to the component or content-item itself. E.g. for a news-item in a news \n   overview.\n  - `ref` - Create link to a referenced content-item. E.g. for a banner.\n  - `href` -  Used by `parseAndRewriteLinks()` to create links using a href only.\n- `link` - `Object` the component configuration or content-object that is linking to itself or \n referenced another content-item.\n- `linkText` - `JSX | Function` HTML to wrap inside the link. Is a function so that it can include HTML.\n- `className` - `String` classnames to add to the link element\n\n#### Return types\n\n`JSX` returns link as JSX object that can be included as a variable anywhere within the return section \nof a React component's render method.\n\n### `getImageUrl(imageRef, pageModel, preview)`\n\nCreates link to URL of image in case BloomReach Experience is used for serving images.\n\n#### Arguments\n\n- `imageRef` - `String` JSON Pointer that references the image.\n- `pageModel` - `Object` since this function is a pure JavaScript function it can't get Page Model from \n context, so it has to be provided as function parameter. The Page Model is used to retrieve the image.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by \n `<RenderCmsComponent>` can pass the prop `this.props.preview`.\n\n#### Return types\n\n`String` returns URL to image.\n\n### `getNestedObject(nestedObject, pathArray)`\n\nReturns a nested object or value using a path array. Useful when you need to access deeply nested \nobjects/values without having to string null checks together.\n\n#### Arguments\n\n- `nestedObject` - `Object` the object containing the nested object or value.\n- `pathArray` - `Array` contains the path to the nested object as an array.\n\n#### Return types\n\n`Object|null` returns the nested object if found, otherwise returns null. \n\n### `parseAndRewriteLinks(html, preview)`\n\nParses HTML of a rich-text field of a content-item for rewriting links in HTML to internal links. Uses \nthe `createLink` function passed to `<CmsPage>` for constructing internal links.\n\n#### Arguments\n\n- `html` - `String` value of rich-text field of a content-item. Should contain HTML only.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by \n `<RenderCmsComponent>` can pass the prop `this.props.preview`.\n\n#### Return types\n\n`JSX` returns parsed and rewrited HTML as JSX.\n\n### `parseDate(date)`\n\nParses date-field of a content item and returns date as a string.\n\n#### Arguments\n\n- `date` - `String` takes raw value of a date-field as input, following the ISO 8601:2000 format.\n\n#### Return types\n\n`String` returns date in full date format.\n\n## Release notes\n\n### Version 0.4.0\n\nAdded support for rendering static CMS components.\n- Added new property `renderComponent` to `<RenderCmsComponent>` which allows you to render a static \n component. This only works in combination with the `path` property, which should contain the relative \n path to the component.\n- Renamed `<ManageContentButton>` to `<CmsEditButton>` and exported it so it can be used by apps. This \n component is now more generic so it can also be used to generate edit buttons in the CMS for site menus.\n- Moved `<CmsMenu>` component out of SDK and into the example apps.\n\n\n### Version 0.3.0\n\nAdded extra checks so that `<div>` elements needed for CMS preview are only inserted in preview mode.\n\n### Version 0.2.0\n\nThis version includes significant changes. Please make sure to update your components using the upgrade \nsteps further down.\n- Changed `cmsUrls` property to support different live and preview URLs.\n- Changed `urlPath` property to `request` property which no longer takes URL-path as string, but an \n object with hostname and URL-path. This property should be passed to `<CmsPage>`.\n- Changed helper method `getApiUrl()` to take `request` property as parameter instead of `urlPath`.\n- Changed helper method `parseAndRewriteLinks()` to take an extra parameter: `preview`.\n- Changed helper method `getImageUrl()` to take an extra parameter: `preview`.\n\nUpgrade steps:\n- Modify `cmsUrls` property to include URLs for live and preview using the properties `live` and \n `preview` respectively. Please note that the `cms` prefix has been removed from all URL properties. So `cmsHostname` has become `hostname`. Preview URLs are optional. For example:\n  ```js\n  const cmsUrls = {\n    live: {\n      hostname: bloomreach.com\n    },\n    preview: {\n      hostname: cms.bloomreach.com\n    }\n  }\n  ```\n- Pass current request details through `request` property to `<CmsPage>`. This was previously done \n through the `urlPath` property. The `request` property should be an object that contains the hostname \n and path as properties `hostname` and `path` respectively. For example:\n  ```jsx\n  const request = { hostname: window.location.hostname, path: window.location.path };\n  <CmsPage componentDefinitions={componentDefinitions} request={request}>\n  ```\n- Update usage of `getApiUrl` to pass `request` property (see previous bullet) instead of URL-path.\n- Update usage of helper methods `getImageUrl()` and `parseAndRewriteLinks()` to include the preview \n parameter. Components rendered by `<RenderCmsComponent>` have the preview value passed as prop \n `this.props.preview`.\n\n## FAQ / Troubleshooting\n\nNothing here yet :)\n\n## Author\n\nRobbert Kauffman - BloomReach\n","gitHead":"2019829ac84f65dda0087d546409f4babfca221b","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"rkauffman","email":"robbertkauffman@gmail.com"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.2.0","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.8.0","dependencies":{"jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.4.0-rc1_1537132331480_0.366736724733395","host":"s3://npm-registry-packages"}},"0.4.1-rc1":{"name":"bloomreach-experience-react-sdk","version":"0.4.1-rc1","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.4.1-rc1","maintainers":[{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"c01b2bfd3cc6331df0dd469906a44592bb64a85a","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.4.1-rc1.tgz","fileCount":27,"integrity":"sha512-XhSYurR4orxCyoqFLr8gwiAZtZmBD09ZDGftTfprvw3G0uFo1eNpKO5bwgGEsCjnb/EzX+THPFZrMsjbz6fKyg==","signatures":[{"sig":"MEUCIEEn8LXHoGNVEt14q9xvNY5Kow6So8pEHezENKFMzoRAAiEAkAhPNBnxMuRwYvXQRG+K1qxNKccQfZOYXdv1VbWAJJ4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":240301,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbovvsCRA9TVsSAnZWagAAjPsQAJmZn47WPLpS1MFOy6Pf\noFoauhMRmGr/AvVCvcw+8x0cXtMMFPTAQPgcGmE7AFhhiJczT5gCmX/jXT3u\noKnsd9Fg7z9A/bSMJSUj8ZtcLejjhJegp5bxPzYmTh03W6d9sxh5ZREr0Lzs\nqE8+jl0gh3ZfKGcZsPydy3e5Wa8gbZRKPyBhm0REG+AQt6sYlC03agk+i2Ve\nHt64J3eE497yWcGNaEUsKxC46YJjFu7Z4r+wBaR030ChOztj19EfIbxudGn4\nQYd0xlnmvLmmwqZBR63qZ5KRClNqu86uYOwYUapRPN6FV27ooYktVeCMGx8F\ne4V2EOq8VTjQH/SslIv5DmNYClnjfPs/Jn2b8ZuGVzwLmGY21bRr3MHF8xEf\nJ5moFX55OzEhBwGmeOWgYEaS/P5UHj36wECNmBjqtQETAs3gswNP7LoYYIpu\nlMdlDTpBXZOSEhdWkHEcTMqfjWqe7F7RFD9LQ+cM9Q6XehC06TJdr77wchwg\nyGPe1UVY6gz1CUjG/2DhlIRcmKmThhak2Pac0POVoTKVJYlHi/Yt/VgIRxEg\nw8X0TIzWp9rt5EOmjkJCtUl09IIVZKBiwHQgP2HiJUmbdfd87k4c8e9cRMt4\nnJXttaXxItR0woV+zXCxPuyBeaxFESxXFCLiLtQNyEax2lYtRMZBehYhp9ab\nOVuW\r\n=9Mbt\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","readme":"# BloomReach Experience SDK for React\n\nSDK for powering content and components in React applications by [BloomReach Experience](https://www.bloomreach.com/en/products/experience). \nThis library makes integrating a React app with BloomReach Experience a breeze. It supports both \nclient-side- and server-side rendered/isomorphic React apps. \n\nBloomReach Experience allows you to use an external front-end such as React for rendering while still \nproviding a native-like authoring experience, such as integrated preview, in-context editing, drag & \ndrop, server-side personalization. For more information on this approach, see [A new approach to \nintegrating SPA's with WCM: Fixing what's wrong with headless integrations](https://www.bloomreach.com/en/blog/2018/03/a-new-approach-to-integrating-spas-with-wcm-fixing-what%E2%80%99s-wrong-with-headless-integrations.html).\n\n## Install\n\n```bash\nnpm install --save bloomreach-experience-react-sdk\n```\n\n## Usage\n\n```jsx\nimport React from 'react'\nimport { CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\nconst componentDefinitions = {\n  \"MyCustomComponent\": { component: MyCustomComponent }\n}\n\nclass MyApp extends React.Component {\n  render() {\n    const request = { hostname: window.location.hostname, path: window.location.pathname };\n    return (\n      <CmsPage componentDefinitions={componentDefinitions} request={request}>\n        { () =>\n          <RenderCmsComponent />\n        }\n      </CmsPage>\n    )\n  }\n}\n```\n\nAt a minimum, `<CmsPage>` and `<RenderCmsComponent>` should be imported in the React app.\n\n`<CmsPage>` fetches the Page Model when it is not supplied as a prop (see section on server-side \nrendering); it fetches updates to the page model on component changes in the CMS; and it initializes and \nmanages state, and provides this as context to `<RenderCmsComponent>`. The `<CmsPage>` component can be \nput anywhere within the React App.\n\n`<RenderCmsComponent>` renders components based on the Page Model API response. It consumes the state \nfrom `<CmsPage>` and renders the container components and any content referenced from the components as \ncontained in the Page Model API response. The `<RenderCmsComponent>` should be nested within `<CmsPage>` \nand placed in the React app at the exact location where you want BloomReach Experience to control what \ncomponents and content is rendered.\n\nPlease note that `<CmsPage>` takes children as a function instead of as a prop, because it is not \npossible to provide state through context providers due to a bug in React currently. So make sure to \nwrap any children of `<CmsPage>` in a function, as in the following example:\n\n ```jsx\n{ () =>\n  // any children go here\n  <h1>Blooming is what I do</h1>\n}\n ```\n\n`<CmsPage>` takes two props: `componentDefinitions` and `request`.\n\nThe `request` prop is used to fetch the Page Model for the current page; and to detect whether \npreview mode is active so that meta-data for Channel Manager functionality (e.g. in-context editing) is \nincluded in the HTML, and consequently Channel Manager functionality is enabled.\n\nFinally, component definitions are supplied through the `componentDefinitions` prop. The component \ndefinitions tell `<RenderCmsComponent>` what React component to render by mapping these to the \n*hst:label* of a CMS catalog component.\n\n## Server-side rendering\n\nFor server-side rendering (e.g. using [Next.js](https://github.com/zeit/next.js)) you need to fetch the \nPage Model API server-side and supply it as a prop to `<CmsPage>`. Apart from this the usage is the same \nas with client-side rendering.\n\nThe helper function `getApiUrl()` can be used to generate the Page Model API URL using the current \nrequest.\n\nIt is important to pass cookies from the initial request and supply these with the request header of the \nPage Model API request. Otherwise you will get a 403 error in preview mode.\n\nFinally, to get preview to work for server-side rendered apps you can use a reverse proxy to route \nrequests from BloomReach's site preview to the React App-server. For more details, see section *3.2 \nServer-side apps* of the Hippo Lab: [Integrate a React application with BloomReach Experience](https://www.onehippo.org/labs/integrate-a-react-application-with-bloomreach-experience.html).\n\n```jsx\nimport fetch from 'isomorphic-unfetch'\nimport { getApiUrl, CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\n// setting pageModel to empty list instead of null value,\n// as otherwise the API will be fetched client-side again after server-side fetch errors\nlet pageModel = {}\n\nconst request = { hostname: req.headers.host, path: asPath }\nconst url = getApiUrl(request, {})\n// pass cookies of initial request for CMS preview\nconst response = await fetch(url, {headers: {'Cookie': req.headers.cookie}})\n\nif (response.ok) {\n  try {\n    pageModel = await response.json()\n  } catch (err) {\n    console.log(`Error! Could not convert response to JSON for URL: ${url}`)\n  }\n} else {\n  console.log(`Error! Status code ${response.status} while fetching CMS page data for URL: ${url}`)\n}\n```  \n\n## Example React apps\n\nThere are two example React apps available that use the SDK. One client-side rendered, and one \nserver-side rendered using [Next.js](https://github.com/zeit/next.js). You can find the [example apps on \nGithub](https://github.com/bloomreach/experience-react-sdk/tree/master/examples).\n\n## Creating custom components\n\nAny components that are supplied through the `compenentDefinitions` prop can be any type of valid React \ncomponent, including functional components. Props are passed to these components as context so that you \ncan access the components' configuration, content, etc. See more information below.\n\n### Props\n\nThe following props are passed to a component that is rendered by `<RenderCmsComponent>`:\n- `configuration` - `Object` component configuration. Contains the contributed models, raw parameters \n and resolved parameters. Content included in the component's model is not serialized as part of the \n component's configuration but in a separate content object, and a JSON Pointer reference is used to \n link to the actual content object. This is done to prevent content from being included multiple times \n in the API response when referenced multiple times on a page. \n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview mode is active based on current URL supplied through \n `request` prop of `<CmsPage>`.\n\nFor more information on the Page Model API response, see the [Swagger documentation](https://www.onehippo.org/library/concepts/spa-plus/page-model-api/swagger-api-documentation.html).\n\n### Example\n\n```jsx\nimport React from 'react'\nimport NewsItem from './news-item'\nimport { getNestedObject } from 'bloomreach-experience-react-sdk'\n\nexport default class NewsList extends React.Component {\n  render() {\n    const preview = this.props.preview\n    const pageModel = this.props.pageModel\n    const configuration = this.props.configuration\n\n    // return placeholder if no list is set on component\n    const list = getNestedObject(configuration, ['models', 'pageable', 'items'])\n    if (!list && preview) {\n      return (<p>Click to configure {configuration.label}</p>)\n    } else if (!list) {\n      // don't render placeholder outside of preview mode\n      return null\n    }\n\n    // build list of news articles\n    const listItems = list.map((listItem, index) => {\n      if ('$ref' in listItem) {\n        return (<NewsItem contentRef={listItem.$ref} pageModel={pageModel} preview={preview} key={index}/>)\n      }\n    })\n\n    return (\n      <div className=\"row\">\n        <div className=\"col-sm-12 news-list\">\n          {listItems}\n        </div>\n      </div>\n    )\n  }\n}\n```\n\n### Content components\n\nComponents that reference a single content-item (e.g. the Banner component) can use a convenient \nwrapper-class that looks up the content and passes it as a prop. See below.\n\nTo enable this, the property `wrapInContentComponent: true` has to be set on the component in the \n`componentDefinitions` prop. See `componentDefinitions` in the API section for more details.\n\n#### Props\n\n- `content` - `Object` raw content object that contains the content-item's fields and field-values. Any \n references to other content-items (e.g. images) are serialized as JSON Pointers.\n- `manageContentButton` - `React.Component` for placement and rendering of the [Manage Content Button](https://www.onehippo.org/library/concepts/component-development/render-manage-content-button.html)\n in preview mode in CMS.\n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview is active based on current URL supplied through `request` \n prop of `<CmsPage>`.\n\n#### Example\n\n```jsx\nimport React from 'react'\n\nconst content = this.props.content;\nconst manageContentButton = this.props.manageContentButton;\n\nclass Banner extends React.Component {\n  render() {\n    return (\n      <div className=\"my-content-component\">\n        { manageContentButton && manageContentButton }\n        { content.title && content.title }\n      </div>)\n  }\n}\n```\n\n### Static CMS components\n\nStatic CMS components are components that are defined by developers / administrators and cannot be  \nmodified by users in the CMS. However, any content or site menus these components reference can be \nchanged by users in the CMS.\n\nSince `<RenderCmsComponent>` only renders container components (drag-and-drop components) by default, \nyou have to specify two additional properties in order to render a static CMS component: the `path` \nproperty to point to the relative path of the component, and `renderComponent` to specify which React \ncomponent to use for rendering the component. See the example below.\n\n```jsx\n<RenderCmsComponent path={'menu'} renderComponent={CmsMenu} />\n```\n\n### More component examples\n\nFor more detailed examples, see the components included in the [example applications](https://github.com/bloomreach/experience-react-sdk/tree/master/examples/client-side-rendered/src/components). \n\n### Helper functions\n\nAdditionally, there are a variety of helper functions available. See the examples below. For full \ndetails on the APIs, see the API section.\n\n```jsx\nimport { createLink, getImageUrl, getNestedObject, parseAndRewriteLinks, parseDate } from 'bloomreach-experience-react-sdk'\n\nconst link = createLink('ref', link, linkText, className)\nconst image = getImageUrl(content.image, this.props.pageModel, this.props.preview)\nconst list = getNestedObject(configuration, ['models', 'pageable', 'items', 0])\nconst contentHtml = parseAndRewriteLinks(content.content.value, this.props.preview)\nconst date = parseDate(content.date)\n```\n\n## API\n\n### `<CmsPage>`\n\nThe CmsPage component is a higher-order component that takes care of:\n- Fetching the Page Model for client-side rendering, when not supplied as a prop.\n- Fetching Page Model updates on component changes in the CMS.\n- Initializing and managing state, and providing this as context to `<RenderCmsComponent>`.\n\n#### Properties\n\n- `cmsUrls` - `Object` Override default CMS URL's. (Optional)\n- `componentDefinitions` - `object` Mapping of CMS catalog components to React components. Determines \n what component to render based from the Page Model. (Optional)\n- `createLink` - `Function` Called when creating internal links so that links can be constructed using \n the router library of the React app. (Optional)\n- `pageModel` - `Object` Supply Page Model as prop. Used for server-side-rendering where Page Model API \n is fetched server-side. When supplied, `CmsPage` will not fetch Page Model API on mount, only on \n component updates in CMS. (Optional)\n- `request` - `String` Current URL-path for determining if preview mode is active, and for fetching the \n Page Model for the page that is active. (Required)\n\n###### `cmsUrls` property\n\nProperty that allows you to override the default URL's for fetching the Page Model API. Typically you \nwill only have to define `scheme`, `hostname`, `port`, and `contextPath`. Input object takes the \nfollowing properties (all are optional):\n- `scheme` - `String` scheme (default: *http*)\n- `hostname` - `String` hostname (default: *localhost*)\n- `port` - `number` port number (default: *8080*)\n- `contextPath` - `String` site context-path (default: *site*)\n- `channelPath` - `String` path to the used channel, if channel is accessed through a subpath\n- `previewPrefix` - `String` preview-prefix used by CMS (default: *_cmsinternal*)\n- `apiPath` - `String` path to Page Model API as subpath (default: *resourceapi*)\n- `apiComponentRenderingUrlSuffix` - `String` (default: *?_hn:type=component-rendering&_hn:ref=*)\n\n###### `componentDefinitions` property\n\nMaps CMS catalog components to React components. Expects as input an object with `hst:label` of the CMS \ncomponents as keys and as value another object. The nested object has the mandatory property `component` \nwho's value maps the CMS component to a React component. See the example below:\n\n```js\nconst componentDefinitions = {\n  \"MyCustomCmsComponent\": { component: MyCustomReactComponent },\n  \"AnotherCmsComponent\": { component: AnotherReactComponent, wrapInContentComponent: true }\n};\n```\n\nAdditionally, the property `wrapInContentComponent: true` can be used for components that reference a \nsingle content-item. When this property is set on a component, it will be wrapped in a convenient \nwrapper class. See section *Content components*.\n\n##### `createLink` property\n\nCalled when creating internal links so that links can be constructed using the router library of the \nReact app. \n\nTakes `Function` as input. The function should return valid JSX and have three parameters:\n- `href` - `String` href of link\n- `linkText` - `Function` contains the HTML that is wrapped inside the link. Is a function so that it \n can include HTML.\n- `className` - `String` classnames to add to the link element\n\nFor example:\n```jsx\nconst createLink = (href, linkText, className) => {\n  return (<Link className={className} to={href}>{linkText()}</Link>)\n}\n```\n\n##### `pageModel` property\n\nPage Model can be supplied as a prop when using a server-side rendered / isomorphic React framework. \nWhen supplied, `<CmsPage>` will not fetch the Page Model API client-side. \n\n##### `request` property\n\nTakes `Object` as input with properties `hostname` and `path`, both of type `String`. The property \n`hostname` should contain the hostname for the current request (client-side this is \nwindow.location.hostname). The property `path` should contain the URL-path for the current request \n(client-side this is window.location.pathname);\n\n### `<RenderCmsComponent>`\n\nRenders a CMS component and all of its children using the Page Model supplied by `<CmsPage>`. Will \nrender the entire Page Model by default.\n\n#### Properties\n\n- `path` - `String` path to a component (static CMS component), container or container-item in the Page \n Model to render only that component and its children. If no path is supplied, entire Page Model will be \n rendered. \n- `renderComponent` - `React.Component` render a static CMS component using specified React component. \n Only works in combination with `path` property, which should specify path to the static CMS component. \n Site menus that are rendered this way can leverage the `<CmsEditButton>` component for rendering edit \n buttons in the CMS.\n\n#### Example\n\n```jsx\n<RenderCmsComponent path={'menu'} renderComponent={CmsMenu} />\n```\n\n### `<CmsEditButton>`\n\nInserts meta-data for either a content-item or site menu for placing an edit button in preview mode in \nthe CMS. Content-items that are rendered by a content component using `wrapInContentComponent: true` do \nnot need to use this component, but should use the `manageContentButton` prop that passes the meta-data.\n\n#### Properties\n\n- `configuration` - `Object` configuration of the site menu (not the component configuration containing \nthe menu) or the content-item object which has the `_meta` object in its root.\n- `preview` - `Boolean` toggle to prevent edit buttons from being rendered outside of preview.\n\n### `getApiUrl(request, [newCmsUrls])`\n\nHelper function for generating URL to the Page Model API for server-side fetching of the Page Model. \n\n#### Arguments\n\n- `request` - `Object` containing hostname and URL-path as properties `hostname` and `path` \n respectively. See the `request` property section above.\n- `newCmsUrls` - `Object` takes `cmsUrls` property as input to override default CMS URL's\n\n#### Return types\n\n`String` returns URL for fetching Page Model API\n\n### `createLink(linkType, link, linkText, className)`\n\nCreates a link to either a component or content-item itself or a referenced content-item (can be a \ndocument, image or asset) and returns the link as JSX.  \n\n#### Arguments\n\n- `linkType` - `String` type of link to create. Valid values are `self`, `ref` or `href`.\n  - `self` - Create link to the component or content-item itself. E.g. for a news-item in a news \n   overview.\n  - `ref` - Create link to a referenced content-item. E.g. for a banner.\n  - `href` -  Used by `parseAndRewriteLinks()` to create links using a href only.\n- `link` - `Object` the component configuration or content-object that is linking to itself or \n referenced another content-item.\n- `linkText` - `JSX | Function` HTML to wrap inside the link. Is a function so that it can include HTML.\n- `className` - `String` classnames to add to the link element\n\n#### Return types\n\n`JSX` returns link as JSX object that can be included as a variable anywhere within the return section \nof a React component's render method.\n\n### `getImageUrl(imageRef, pageModel, preview)`\n\nCreates link to URL of image in case BloomReach Experience is used for serving images.\n\n#### Arguments\n\n- `imageRef` - `String` JSON Pointer that references the image.\n- `pageModel` - `Object` since this function is a pure JavaScript function it can't get Page Model from \n context, so it has to be provided as function parameter. The Page Model is used to retrieve the image.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by \n `<RenderCmsComponent>` can pass the prop `this.props.preview`.\n\n#### Return types\n\n`String` returns URL to image.\n\n### `getNestedObject(nestedObject, pathArray)`\n\nReturns a nested object or value using a path array. Useful when you need to access deeply nested \nobjects/values without having to string null checks together.\n\n#### Arguments\n\n- `nestedObject` - `Object` the object containing the nested object or value.\n- `pathArray` - `Array` contains the path to the nested object as an array.\n\n#### Return types\n\n`Object|null` returns the nested object if found, otherwise returns null. \n\n### `parseAndRewriteLinks(html, preview)`\n\nParses HTML of a rich-text field of a content-item for rewriting links in HTML to internal links. Uses \nthe `createLink` function passed to `<CmsPage>` for constructing internal links.\n\n#### Arguments\n\n- `html` - `String` value of rich-text field of a content-item. Should contain HTML only.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by \n `<RenderCmsComponent>` can pass the prop `this.props.preview`.\n\n#### Return types\n\n`JSX` returns parsed and rewrited HTML as JSX.\n\n### `parseDate(date)`\n\nParses date-field of a content item and returns date as a string.\n\n#### Arguments\n\n- `date` - `String` takes raw value of a date-field as input, following the ISO 8601:2000 format.\n\n#### Return types\n\n`String` returns date in full date format.\n\n## Release notes\n\n### Version 0.4.0\n\nAdded support for rendering static CMS components.\n- Added new property `renderComponent` to `<RenderCmsComponent>` which allows you to render a static \n component. This only works in combination with the `path` property, which should contain the relative \n path to the component.\n- Renamed `<ManageContentButton>` to `<CmsEditButton>` and exported it so it can be used by apps. This \n component is now more generic so it can also be used to generate edit buttons in the CMS for site menus.\n- Moved `<CmsMenu>` component out of SDK and into the example apps.\n\n\n### Version 0.3.0\n\nAdded extra checks so that `<div>` elements needed for CMS preview are only inserted in preview mode.\n\n### Version 0.2.0\n\nThis version includes significant changes. Please make sure to update your components using the upgrade \nsteps further down.\n- Changed `cmsUrls` property to support different live and preview URLs.\n- Changed `urlPath` property to `request` property which no longer takes URL-path as string, but an \n object with hostname and URL-path. This property should be passed to `<CmsPage>`.\n- Changed helper method `getApiUrl()` to take `request` property as parameter instead of `urlPath`.\n- Changed helper method `parseAndRewriteLinks()` to take an extra parameter: `preview`.\n- Changed helper method `getImageUrl()` to take an extra parameter: `preview`.\n\nUpgrade steps:\n- Modify `cmsUrls` property to include URLs for live and preview using the properties `live` and \n `preview` respectively. Please note that the `cms` prefix has been removed from all URL properties. So `cmsHostname` has become `hostname`. Preview URLs are optional. For example:\n  ```js\n  const cmsUrls = {\n    live: {\n      hostname: bloomreach.com\n    },\n    preview: {\n      hostname: cms.bloomreach.com\n    }\n  }\n  ```\n- Pass current request details through `request` property to `<CmsPage>`. This was previously done \n through the `urlPath` property. The `request` property should be an object that contains the hostname \n and path as properties `hostname` and `path` respectively. For example:\n  ```jsx\n  const request = { hostname: window.location.hostname, path: window.location.path };\n  <CmsPage componentDefinitions={componentDefinitions} request={request}>\n  ```\n- Update usage of `getApiUrl` to pass `request` property (see previous bullet) instead of URL-path.\n- Update usage of helper methods `getImageUrl()` and `parseAndRewriteLinks()` to include the preview \n parameter. Components rendered by `<RenderCmsComponent>` have the preview value passed as prop \n `this.props.preview`.\n\n## FAQ / Troubleshooting\n\nNothing here yet :)\n\n## Author\n\nRobbert Kauffman - BloomReach\n","gitHead":"4055f40903279fff41bfbba746466d86d0ddd113","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"rkauffman","email":"robbertkauffman@gmail.com"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.2.0","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.8.0","dependencies":{"jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.4.1-rc1_1537407979911_0.0637562123229638","host":"s3://npm-registry-packages"}},"0.4.1":{"name":"bloomreach-experience-react-sdk","version":"0.4.1","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.4.1","maintainers":[{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"a370445706b145216fde0dc39789725f8f40f389","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.4.1.tgz","fileCount":27,"integrity":"sha512-IlZTXvvvzTGSMYBFrB4diq7GMMz92bfWvFMhVztnAInKytyylJSZb3ON5RMcB9te7igtykDBYUWMRRhH25YTSw==","signatures":[{"sig":"MEYCIQDNzUuFuFdNFmzAnY5l2f3WKzrnwWsoiRrpHWjt+hngSgIhALZRRXOmKS1VIN8V8jvsJmFPVKkbWVWv1Br5LW+E90R8","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":240297,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbrpVTCRA9TVsSAnZWagAAG9EP/0Z/OMXeTOTDQkzePdfH\nxPR5w/CTrU1MW02x9rEKWHfHeCLl/rmBrUIJfC5YXlnceuYmf5gnEZd3VdC0\nGNaWkgoxYjiJeGtLhAZJU1EuSVZHDrXIjxdDWX1cAXiwppD9bm/u1UiWc2gP\n05v6akE1MUesuJYKerfrzw0zvP3qQQlqkdACZIY2ClSYiHz76jj4Y66XA9er\nfQ1r7LJoBHodu2vpcXz1Isa6B51UF884Vl/Y40SETNHNCBeGmVMuRz7ERSeV\naZTP9RE2z3p6EGsuV8UvtHCqYNqCrd+UuBOokCJvj+QnDU2aG49/rRN2ETtb\nx44gy00fH0WtzEaeX5M+zB5HIHa9/9Sa0TDWH56K0Tv+AsaGJPaMso/WBwwB\nPhDFj2l1/PbJYsXb6rjENZpuZp1nph1s6ILOoTTXEIKIvRgos78W1LY8Kl/V\n4xUgzQjRSC6A/mVhhwA9xiJKNUBMwUdE0LS9MSwauhx1mLLD7I/HPEZ+d/FJ\nbccpbdQo50N54tlIWqCRPEKr0sbfDcEamfxzjBWnbpAh0RmE+FezxaqFCiLv\nPoGIetuLtv+eIN0NSdOrXpDyGQQ2pnN8RHPrVbQ/BVQgviLphZQPTQJuYBh2\nO1a7G9izgo3107n0w3JOZv+yJdyY2PudLBvD/OxAI8WtSYWBZZkW3BDehlfB\nTqby\r\n=/nRO\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","gitHead":"be3532a913fa32b613c1f0e87be331c483de8317","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"rkauffman","email":"robbertkauffman@gmail.com"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.2.0","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.8.0","dependencies":{"jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.4.1_1538168146324_0.9455095589523035","host":"s3://npm-registry-packages"}},"0.4.2-rc1":{"name":"bloomreach-experience-react-sdk","version":"0.4.2-rc1","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.4.2-rc1","maintainers":[{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"ebbbbfeb9dc2c5e2780772f52ec4ef725c07b332","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.4.2-rc1.tgz","fileCount":27,"integrity":"sha512-We5XRNTa/1DzfpvfXMjSXHI9FRxHihLfFxD/0rDvfdUd/RBl9J1Sw9giKCr8NSIozQzPzPb65+id2FRvtPnSbQ==","signatures":[{"sig":"MEUCIQCnewbgAMAQ37iZoz/WX2mXIFYrZEH10ZRmU1MWvp19bAIgBipbx8uvY+NNBFK8FZJIDJzvu5ClaA+bVWBpdDE+Oe8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":240738,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbrpdrCRA9TVsSAnZWagAAWo8P/R5nvqdqNq+92yiuj5kZ\nZNgXhfwbRWLW/HtgEmbOz5G+RwZTUWj3s5vv0kVSA+6L2m7xhhcsLa9hW9sM\nw/zwEx+jkk6AzdJJUly1LPVZ8XM8v9i1aUihV1n4bc7WXQbEd2u7poSX6Pod\nlpeyvHtrLrAJpL60E43d3XWe97Uos/Dhse6rxQ1RDbSwOYPt1xEurrH366gB\neIAkscHZOunMqFXaQ9XVklCOXAjxJ/y048MqfHHrCIpQzgTr5MPxo8MODKQr\nFE77tB7cE6sQ6fY2CqKSJkpe85ArUSNkeqBnqAOIH3VNiFjGTfIRPl/6vuy8\nzs6kQjE3VXFfoFwaS/ZNfBbB6oCrWJZ443E76JJjvDYUfyYQ7RnKpitJz3KI\nVZC9EB4Y0g0+2oTAC8TuTf8e5uVR7mVES1i6emo4EipPNTRbbt9HWDWjnyim\n1M/WvXlrLrat7gqmUHYLPsbtaEJUgRaab9gIoXn17LRkZZ0D2Lw8DeTpJz/8\nroHc1MWoPCtokzxhksp0IDIb+sPUt8nhzPXmoBbz0WI6wmuI55vZofzrHyga\nK9vG0KMCy53moV8NMyZmXsCeXbVVzJsX+VKl/eHnQbo9bs+fNqGYzU+IsDrM\ndHktEfW4ar2mzKIpUL2QQoFxl2jKEZekgOvvaZVEiLvnUc55msm7yRrIxucr\ntghL\r\n=Z0ad\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","readme":"# BloomReach Experience SDK for React\n\nSDK for powering content and components in React applications by [BloomReach Experience](https://www.bloomreach.com/en/products/experience). \nThis library makes integrating a React app with BloomReach Experience a breeze. It supports both \nclient-side- and server-side rendered/isomorphic React apps. \n\nBloomReach Experience allows you to use an external front-end such as React for rendering while still \nproviding a native-like authoring experience, such as integrated preview, in-context editing, drag & \ndrop, server-side personalization. For more information on this approach, see [A new approach to \nintegrating SPA's with WCM: Fixing what's wrong with headless integrations](https://www.bloomreach.com/en/blog/2018/03/a-new-approach-to-integrating-spas-with-wcm-fixing-what%E2%80%99s-wrong-with-headless-integrations.html).\n\n## Install\n\n```bash\nnpm install --save bloomreach-experience-react-sdk\n```\n\n## Usage\n\n```jsx\nimport React from 'react'\nimport { CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\nconst componentDefinitions = {\n  \"MyCustomComponent\": { component: MyCustomComponent }\n}\n\nclass MyApp extends React.Component {\n  render() {\n    const request = { hostname: window.location.hostname, path: window.location.pathname };\n    return (\n      <CmsPage componentDefinitions={componentDefinitions} request={request}>\n        { () =>\n          <RenderCmsComponent />\n        }\n      </CmsPage>\n    )\n  }\n}\n```\n\nAt a minimum, `<CmsPage>` and `<RenderCmsComponent>` should be imported in the React app.\n\n`<CmsPage>` fetches the Page Model when it is not supplied as a prop (see section on server-side \nrendering); it fetches updates to the page model on component changes in the CMS; and it initializes and \nmanages state, and provides this as context to `<RenderCmsComponent>`. The `<CmsPage>` component can be \nput anywhere within the React App.\n\n`<RenderCmsComponent>` renders components based on the Page Model API response. It consumes the state \nfrom `<CmsPage>` and renders the container components and any content referenced from the components as \ncontained in the Page Model API response. The `<RenderCmsComponent>` should be nested within `<CmsPage>` \nand placed in the React app at the exact location where you want BloomReach Experience to control what \ncomponents and content is rendered.\n\nPlease note that `<CmsPage>` takes children as a function instead of as a prop, because it is not \npossible to provide state through context providers due to a bug in React currently. So make sure to \nwrap any children of `<CmsPage>` in a function, as in the following example:\n\n ```jsx\n{ () =>\n  // any children go here\n  <h1>Blooming is what I do</h1>\n}\n ```\n\n`<CmsPage>` takes two props: `componentDefinitions` and `request`.\n\nThe `request` prop is used to fetch the Page Model for the current page; and to detect whether \npreview mode is active so that meta-data for Channel Manager functionality (e.g. in-context editing) is \nincluded in the HTML, and consequently Channel Manager functionality is enabled.\n\nFinally, component definitions are supplied through the `componentDefinitions` prop. The component \ndefinitions tell `<RenderCmsComponent>` what React component to render by mapping these to the \n*hst:label* of a CMS catalog component.\n\n## Server-side rendering\n\nFor server-side rendering (e.g. using [Next.js](https://github.com/zeit/next.js)) you need to fetch the \nPage Model API server-side and supply it as a prop to `<CmsPage>`. Apart from this the usage is the same \nas with client-side rendering.\n\nThe helper function `getApiUrl()` can be used to generate the Page Model API URL using the current \nrequest.\n\nIt is important to pass cookies from the initial request and supply these with the request header of the \nPage Model API request. Otherwise you will get a 403 error in preview mode.\n\nFinally, to get preview to work for server-side rendered apps you can use a reverse proxy to route \nrequests from BloomReach's site preview to the React App-server. For more details, see section *3.2 \nServer-side apps* of the Hippo Lab: [Integrate a React application with BloomReach Experience](https://www.onehippo.org/labs/integrate-a-react-application-with-bloomreach-experience.html).\n\n```jsx\nimport fetch from 'isomorphic-unfetch'\nimport { getApiUrl, CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\n// setting pageModel to empty list instead of null value,\n// as otherwise the API will be fetched client-side again after server-side fetch errors\nlet pageModel = {}\n\nconst request = { hostname: req.headers.host, path: asPath }\nconst url = getApiUrl(request, {})\n// pass cookies of initial request for CMS preview\nconst response = await fetch(url, {headers: {'Cookie': req.headers.cookie}})\n\nif (response.ok) {\n  try {\n    pageModel = await response.json()\n  } catch (err) {\n    console.log(`Error! Could not convert response to JSON for URL: ${url}`)\n  }\n} else {\n  console.log(`Error! Status code ${response.status} while fetching CMS page data for URL: ${url}`)\n}\n```  \n\n## Example React apps\n\nThere are two example React apps available that use the SDK. One client-side rendered, and one \nserver-side rendered using [Next.js](https://github.com/zeit/next.js). You can find the [example apps on \nGithub](https://github.com/bloomreach/experience-react-sdk/tree/master/examples).\n\n## Creating custom components\n\nAny components that are supplied through the `compenentDefinitions` prop can be any type of valid React \ncomponent, including functional components. Props are passed to these components as context so that you \ncan access the components' configuration, content, etc. See more information below.\n\n### Props\n\nThe following props are passed to a component that is rendered by `<RenderCmsComponent>`:\n- `configuration` - `Object` component configuration. Contains the contributed models, raw parameters \n and resolved parameters. Content included in the component's model is not serialized as part of the \n component's configuration but in a separate content object, and a JSON Pointer reference is used to \n link to the actual content object. This is done to prevent content from being included multiple times \n in the API response when referenced multiple times on a page. \n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview mode is active based on current URL supplied through \n `request` prop of `<CmsPage>`.\n\nFor more information on the Page Model API response, see the [Swagger documentation](https://www.onehippo.org/library/concepts/spa-plus/page-model-api/swagger-api-documentation.html).\n\n### Example\n\n```jsx\nimport React from 'react'\nimport NewsItem from './news-item'\nimport { getNestedObject } from 'bloomreach-experience-react-sdk'\n\nexport default class NewsList extends React.Component {\n  render() {\n    const preview = this.props.preview\n    const pageModel = this.props.pageModel\n    const configuration = this.props.configuration\n\n    // return placeholder if no list is set on component\n    const list = getNestedObject(configuration, ['models', 'pageable', 'items'])\n    if (!list && preview) {\n      return (<p>Click to configure {configuration.label}</p>)\n    } else if (!list) {\n      // don't render placeholder outside of preview mode\n      return null\n    }\n\n    // build list of news articles\n    const listItems = list.map((listItem, index) => {\n      if ('$ref' in listItem) {\n        return (<NewsItem contentRef={listItem.$ref} pageModel={pageModel} preview={preview} key={index}/>)\n      }\n    })\n\n    return (\n      <div className=\"row\">\n        <div className=\"col-sm-12 news-list\">\n          {listItems}\n        </div>\n      </div>\n    )\n  }\n}\n```\n\n### Content components\n\nComponents that reference a single content-item (e.g. the Banner component) can use a convenient \nwrapper-class that looks up the content and passes it as a prop. See below.\n\nTo enable this, the property `wrapInContentComponent: true` has to be set on the component in the \n`componentDefinitions` prop. See `componentDefinitions` in the API section for more details.\n\n#### Props\n\n- `content` - `Object` raw content object that contains the content-item's fields and field-values. Any \n references to other content-items (e.g. images) are serialized as JSON Pointers.\n- `manageContentButton` - `React.Component` for placement and rendering of the [Manage Content Button](https://www.onehippo.org/library/concepts/component-development/render-manage-content-button.html)\n in preview mode in CMS.\n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview is active based on current URL supplied through `request` \n prop of `<CmsPage>`.\n\n#### Example\n\n```jsx\nimport React from 'react'\n\nconst content = this.props.content;\nconst manageContentButton = this.props.manageContentButton;\n\nclass Banner extends React.Component {\n  render() {\n    return (\n      <div className=\"my-content-component\">\n        { manageContentButton && manageContentButton }\n        { content.title && content.title }\n      </div>)\n  }\n}\n```\n\n### Static CMS components\n\nStatic CMS components are components that are defined by developers / administrators and cannot be  \nmodified by users in the CMS. However, any content or site menus these components reference can be \nchanged by users in the CMS.\n\nSince `<RenderCmsComponent>` only renders container components (drag-and-drop components) by default, \nyou have to specify two additional properties in order to render a static CMS component: the `path` \nproperty to point to the relative path of the component, and `renderComponent` to specify which React \ncomponent to use for rendering the component. See the example below.\n\n```jsx\n<RenderCmsComponent path={'menu'} renderComponent={CmsMenu} />\n```\n\n### More component examples\n\nFor more detailed examples, see the components included in the [example applications](https://github.com/bloomreach/experience-react-sdk/tree/master/examples/client-side-rendered/src/components). \n\n### Helper functions\n\nAdditionally, there are a variety of helper functions available. See the examples below. For full \ndetails on the APIs, see the API section.\n\n```jsx\nimport { createLink, getImageUrl, getNestedObject, parseAndRewriteLinks, parseDate } from 'bloomreach-experience-react-sdk'\n\nconst link = createLink('ref', link, linkText, className)\nconst image = getImageUrl(content.image, this.props.pageModel, this.props.preview)\nconst list = getNestedObject(configuration, ['models', 'pageable', 'items', 0])\nconst contentHtml = parseAndRewriteLinks(content.content.value, this.props.preview)\nconst date = parseDate(content.date)\n```\n\n## API\n\n### `<CmsPage>`\n\nThe CmsPage component is a higher-order component that takes care of:\n- Fetching the Page Model for client-side rendering, when not supplied as a prop.\n- Fetching Page Model updates on component changes in the CMS.\n- Initializing and managing state, and providing this as context to `<RenderCmsComponent>`.\n\n#### Properties\n\n- `cmsUrls` - `Object` Override default CMS URL's. (Optional)\n- `componentDefinitions` - `object` Mapping of CMS catalog components to React components. Determines \n what component to render based from the Page Model. (Optional)\n- `createLink` - `Function` Called when creating internal links so that links can be constructed using \n the router library of the React app. (Optional)\n- `pageModel` - `Object` Supply Page Model as prop. Used for server-side-rendering where Page Model API \n is fetched server-side. When supplied, `CmsPage` will not fetch Page Model API on mount, only on \n component updates in CMS. (Optional)\n- `request` - `String` Current URL-path for determining if preview mode is active, and for fetching the \n Page Model for the page that is active. (Required)\n\n###### `cmsUrls` property\n\nProperty that allows you to override the default URL's for fetching the Page Model API. Typically you \nwill only have to define `scheme`, `hostname`, `port`, and `contextPath`. Input object takes the \nfollowing properties (all are optional):\n- `scheme` - `String` scheme (default: *http*)\n- `hostname` - `String` hostname (default: *localhost*)\n- `port` - `number` port number (default: *8080*)\n- `contextPath` - `String` site context-path (default: *site*)\n- `channelPath` - `String` path to the used channel, if channel is accessed through a subpath\n- `previewPrefix` - `String` preview-prefix used by CMS (default: *_cmsinternal*)\n- `apiPath` - `String` path to Page Model API as subpath (default: *resourceapi*)\n- `apiComponentRenderingUrlSuffix` - `String` (default: *?_hn:type=component-rendering&_hn:ref=*)\n\n###### `componentDefinitions` property\n\nMaps CMS catalog components to React components. Expects as input an object with `hst:label` of the CMS \ncomponents as keys and as value another object. The nested object has the mandatory property `component` \nwho's value maps the CMS component to a React component. See the example below:\n\n```js\nconst componentDefinitions = {\n  \"MyCustomCmsComponent\": { component: MyCustomReactComponent },\n  \"AnotherCmsComponent\": { component: AnotherReactComponent, wrapInContentComponent: true }\n};\n```\n\nAdditionally, the property `wrapInContentComponent: true` can be used for components that reference a \nsingle content-item. When this property is set on a component, it will be wrapped in a convenient \nwrapper class. See section *Content components*.\n\n##### `createLink` property\n\nCalled when creating internal links so that links can be constructed using the router library of the \nReact app. \n\nTakes `Function` as input. The function should return valid JSX and have three parameters:\n- `href` - `String` href of link\n- `linkText` - `Function` contains the HTML that is wrapped inside the link. Is a function so that it \n can include HTML.\n- `className` - `String` classnames to add to the link element\n\nFor example:\n```jsx\nconst createLink = (href, linkText, className) => {\n  return (<Link className={className} to={href}>{linkText()}</Link>)\n}\n```\n\n##### `pageModel` property\n\nPage Model can be supplied as a prop when using a server-side rendered / isomorphic React framework. \nWhen supplied, `<CmsPage>` will not fetch the Page Model API client-side. \n\n##### `request` property\n\nTakes `Object` as input with properties `hostname` and `path`, both of type `String`. The property \n`hostname` should contain the hostname for the current request (client-side this is \nwindow.location.hostname). The property `path` should contain the URL-path for the current request \n(client-side this is window.location.pathname);\n\n### `<RenderCmsComponent>`\n\nRenders a CMS component and all of its children using the Page Model supplied by `<CmsPage>`. Will \nrender the entire Page Model by default.\n\n#### Properties\n\n- `path` - `String` path to a component (static CMS component), container or container-item in the Page \n Model to render only that component and its children. If no path is supplied, entire Page Model will be \n rendered. \n- `renderComponent` - `React.Component` render a static CMS component using specified React component. \n Only works in combination with `path` property, which should specify path to the static CMS component. \n Site menus that are rendered this way can leverage the `<CmsEditButton>` component for rendering edit \n buttons in the CMS.\n\n#### Example\n\n```jsx\n<RenderCmsComponent path={'menu'} renderComponent={CmsMenu} />\n```\n\n### `<CmsEditButton>`\n\nInserts meta-data for either a content-item or site menu for placing an edit button in preview mode in \nthe CMS. Content-items that are rendered by a content component using `wrapInContentComponent: true` do \nnot need to use this component, but should use the `manageContentButton` prop that passes the meta-data.\n\n#### Properties\n\n- `configuration` - `Object` configuration of the site menu (not the component configuration containing \nthe menu) or the content-item object which has the `_meta` object in its root.\n- `preview` - `Boolean` toggle to prevent edit buttons from being rendered outside of preview.\n\n### `getApiUrl(request, [newCmsUrls])`\n\nHelper function for generating URL to the Page Model API for server-side fetching of the Page Model. \n\n#### Arguments\n\n- `request` - `Object` containing hostname and URL-path as properties `hostname` and `path` \n respectively. See the `request` property section above.\n- `newCmsUrls` - `Object` takes `cmsUrls` property as input to override default CMS URL's\n\n#### Return types\n\n`String` returns URL for fetching Page Model API\n\n### `createLink(linkType, link, linkText, className)`\n\nCreates a link to either a component or content-item itself or a referenced content-item (can be a \ndocument, image or asset) and returns the link as JSX.  \n\n#### Arguments\n\n- `linkType` - `String` type of link to create. Valid values are `self`, `ref` or `href`.\n  - `self` - Create link to the component or content-item itself. E.g. for a news-item in a news \n   overview.\n  - `ref` - Create link to a referenced content-item. E.g. for a banner.\n  - `href` -  Used by `parseAndRewriteLinks()` to create links using a href only.\n- `link` - `Object` the component configuration or content-object that is linking to itself or \n referenced another content-item.\n- `linkText` - `JSX | Function` HTML to wrap inside the link. Is a function so that it can include HTML.\n- `className` - `String` classnames to add to the link element\n\n#### Return types\n\n`JSX` returns link as JSX object that can be included as a variable anywhere within the return section \nof a React component's render method.\n\n### `getImageUrl(imageRef, pageModel, preview)`\n\nCreates link to URL of image in case BloomReach Experience is used for serving images.\n\n#### Arguments\n\n- `imageRef` - `String` JSON Pointer that references the image.\n- `pageModel` - `Object` since this function is a pure JavaScript function it can't get Page Model from \n context, so it has to be provided as function parameter. The Page Model is used to retrieve the image.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by \n `<RenderCmsComponent>` can pass the prop `this.props.preview`.\n\n#### Return types\n\n`String` returns URL to image.\n\n### `getNestedObject(nestedObject, pathArray)`\n\nReturns a nested object or value using a path array. Useful when you need to access deeply nested \nobjects/values without having to string null checks together.\n\n#### Arguments\n\n- `nestedObject` - `Object` the object containing the nested object or value.\n- `pathArray` - `Array` contains the path to the nested object as an array.\n\n#### Return types\n\n`Object|null` returns the nested object if found, otherwise returns null. \n\n### `parseAndRewriteLinks(html, preview)`\n\nParses HTML of a rich-text field of a content-item for rewriting links in HTML to internal links. Uses \nthe `createLink` function passed to `<CmsPage>` for constructing internal links.\n\n#### Arguments\n\n- `html` - `String` value of rich-text field of a content-item. Should contain HTML only.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by \n `<RenderCmsComponent>` can pass the prop `this.props.preview`.\n\n#### Return types\n\n`JSX` returns parsed and rewrited HTML as JSX.\n\n### `parseDate(date)`\n\nParses date-field of a content item and returns date as a string.\n\n#### Arguments\n\n- `date` - `String` takes raw value of a date-field as input, following the ISO 8601:2000 format.\n\n#### Return types\n\n`String` returns date in full date format.\n\n## Release notes\n\n### Version 0.4.0\n\nAdded support for rendering static CMS components.\n- Added new property `renderComponent` to `<RenderCmsComponent>` which allows you to render a static \n component. This only works in combination with the `path` property, which should contain the relative \n path to the component.\n- Renamed `<ManageContentButton>` to `<CmsEditButton>` and exported it so it can be used by apps. This \n component is now more generic so it can also be used to generate edit buttons in the CMS for site menus.\n- Moved `<CmsMenu>` component out of SDK and into the example apps.\n\n\n### Version 0.3.0\n\nAdded extra checks so that `<div>` elements needed for CMS preview are only inserted in preview mode.\n\n### Version 0.2.0\n\nThis version includes significant changes. Please make sure to update your components using the upgrade \nsteps further down.\n- Changed `cmsUrls` property to support different live and preview URLs.\n- Changed `urlPath` property to `request` property which no longer takes URL-path as string, but an \n object with hostname and URL-path. This property should be passed to `<CmsPage>`.\n- Changed helper method `getApiUrl()` to take `request` property as parameter instead of `urlPath`.\n- Changed helper method `parseAndRewriteLinks()` to take an extra parameter: `preview`.\n- Changed helper method `getImageUrl()` to take an extra parameter: `preview`.\n\nUpgrade steps:\n- Modify `cmsUrls` property to include URLs for live and preview using the properties `live` and \n `preview` respectively. Please note that the `cms` prefix has been removed from all URL properties. So `cmsHostname` has become `hostname`. Preview URLs are optional. For example:\n  ```js\n  const cmsUrls = {\n    live: {\n      hostname: bloomreach.com\n    },\n    preview: {\n      hostname: cms.bloomreach.com\n    }\n  }\n  ```\n- Pass current request details through `request` property to `<CmsPage>`. This was previously done \n through the `urlPath` property. The `request` property should be an object that contains the hostname \n and path as properties `hostname` and `path` respectively. For example:\n  ```jsx\n  const request = { hostname: window.location.hostname, path: window.location.path };\n  <CmsPage componentDefinitions={componentDefinitions} request={request}>\n  ```\n- Update usage of `getApiUrl` to pass `request` property (see previous bullet) instead of URL-path.\n- Update usage of helper methods `getImageUrl()` and `parseAndRewriteLinks()` to include the preview \n parameter. Components rendered by `<RenderCmsComponent>` have the preview value passed as prop \n `this.props.preview`.\n\n## FAQ / Troubleshooting\n\nNothing here yet :)\n\n## Author\n\nRobbert Kauffman - BloomReach\n","gitHead":"0ca32b625e1245919bf785e38f4b587448349d20","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"rkauffman","email":"robbertkauffman@gmail.com"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.2.0","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.8.0","dependencies":{"jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.4.2-rc1_1538168683324_0.030180227487502265","host":"s3://npm-registry-packages"}},"0.4.3-rc1":{"name":"bloomreach-experience-react-sdk","version":"0.4.3-rc1","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.4.3-rc1","maintainers":[{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"a856cdc45c6a3ab75c2ab211a5d90cefe30145db","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.4.3-rc1.tgz","fileCount":27,"integrity":"sha512-7BsdysZL+/Wnyz3C85VhMa+nUy4POAD9ScpJdZRcVYNWJxUdsDmjyshedFq8WOKBXUF5NW9LgcWuH4Mq5OTl1g==","signatures":[{"sig":"MEUCIQDYyMJgxU7nDZgoLw4cLU9IRE/Dewrp5ahD0Krt4/nNtAIgXInXX6sXj8paiLeW5WvtSQU+0sV4jDRjCLa0IBntrP0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":240384,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbr6iaCRA9TVsSAnZWagAAkpQQAIaNegNA9OtvXG6L4aDC\nuOXwc9hE8LP8G8IQlHtho69V89kbHk+8x4cPnj568GXjtKVwz901d7IAKljY\nuniHPbEvnBSjiFAO3judljHS8fuJJg6k/zd+0IB7fhBGCd+nrWt/r0sNRHry\n/bkwpKAKP1OZCAEVLry798B2kAzGksZ5GkaaKLOcwLL7KrwcaGGNDugdkoUp\nC9OHkXq8Bh42COeNmFkHnNLRAXWyzvMGzDklvc4Wrk/ZDTL2DCPI7iBUaovf\n5SYhUfD6kSROb2hG8Mfvs3oNt7LwNRzPO9p1hA0OdZsFM2gAJsu8Sie60dNG\ntPNnz2mhI3VfAfTKyND/P6TcWeQgVqDo90FlouqfgQSIxjhPEPrbfdK87zb0\n738crN4Wn7gJWIiy6oGd28zHL1+LimsDLewPIg/XTAaUEdKcUoGgid946Ceo\nJgl4Q28Ilhzhol2bxnLpryKVkNRG2R4kqx9bAQ/+BUBeAaih6/2LWxPsR+j7\nvGHyoBUkwlhL8x2M70BNbfAWl0eCqGu01XoTwRF867MlZKFb26cHyu/Sw3Fh\n6EaVvEjblgvWKMCGtP2oPrNodogqL4nT/eo3W7OM0oYZn81qDgZgXvGPSZAj\nX1QbfHJx7nXqz+ib+qcAwIJCLmVhDpud0T46sSWxKsqzLEMuji+/mBH/PEA/\ngBSb\r\n=LKt1\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","readme":"# BloomReach Experience SDK for React\n\nSDK for powering content and components in React applications by [BloomReach Experience](https://www.bloomreach.com/en/products/experience). \nThis library makes integrating a React app with BloomReach Experience a breeze. It supports both \nclient-side- and server-side rendered/isomorphic React apps. \n\nBloomReach Experience allows you to use an external front-end such as React for rendering while still \nproviding a native-like authoring experience, such as integrated preview, in-context editing, drag & \ndrop, server-side personalization. For more information on this approach, see [A new approach to \nintegrating SPA's with WCM: Fixing what's wrong with headless integrations](https://www.bloomreach.com/en/blog/2018/03/a-new-approach-to-integrating-spas-with-wcm-fixing-what%E2%80%99s-wrong-with-headless-integrations.html).\n\n## Install\n\n```bash\nnpm install --save bloomreach-experience-react-sdk\n```\n\n## Usage\n\n```jsx\nimport React from 'react'\nimport { CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\nconst componentDefinitions = {\n  \"MyCustomComponent\": { component: MyCustomComponent }\n}\n\nclass MyApp extends React.Component {\n  render() {\n    const request = { hostname: window.location.hostname, path: window.location.pathname };\n    return (\n      <CmsPage componentDefinitions={componentDefinitions} request={request}>\n        { () =>\n          <RenderCmsComponent />\n        }\n      </CmsPage>\n    )\n  }\n}\n```\n\nAt a minimum, `<CmsPage>` and `<RenderCmsComponent>` should be imported in the React app.\n\n`<CmsPage>` fetches the Page Model when it is not supplied as a prop (see section on server-side \nrendering); it fetches updates to the page model on component changes in the CMS; and it initializes and \nmanages state, and provides this as context to `<RenderCmsComponent>`. The `<CmsPage>` component can be \nput anywhere within the React App.\n\n`<RenderCmsComponent>` renders components based on the Page Model API response. It consumes the state \nfrom `<CmsPage>` and renders the container components and any content referenced from the components as \ncontained in the Page Model API response. The `<RenderCmsComponent>` should be nested within `<CmsPage>` \nand placed in the React app at the exact location where you want BloomReach Experience to control what \ncomponents and content is rendered.\n\nPlease note that `<CmsPage>` takes children as a function instead of as a prop, because it is not \npossible to provide state through context providers due to a bug in React currently. So make sure to \nwrap any children of `<CmsPage>` in a function, as in the following example:\n\n ```jsx\n{ () =>\n  // any children go here\n  <h1>Blooming is what I do</h1>\n}\n ```\n\n`<CmsPage>` takes two props: `componentDefinitions` and `request`.\n\nThe `request` prop is used to fetch the Page Model for the current page; and to detect whether \npreview mode is active so that meta-data for Channel Manager functionality (e.g. in-context editing) is \nincluded in the HTML, and consequently Channel Manager functionality is enabled.\n\nFinally, component definitions are supplied through the `componentDefinitions` prop. The component \ndefinitions tell `<RenderCmsComponent>` what React component to render by mapping these to the \n*hst:label* of a CMS catalog component.\n\n## Server-side rendering\n\nFor server-side rendering (e.g. using [Next.js](https://github.com/zeit/next.js)) you need to fetch the \nPage Model API server-side and supply it as a prop to `<CmsPage>`. Apart from this the usage is the same \nas with client-side rendering.\n\nThe helper function `getApiUrl()` can be used to generate the Page Model API URL using the current \nrequest.\n\nIt is important to pass cookies from the initial request and supply these with the request header of the \nPage Model API request. Otherwise you will get a 403 error in preview mode.\n\nFinally, to get preview to work for server-side rendered apps you can use a reverse proxy to route \nrequests from BloomReach's site preview to the React App-server. For more details, see section *3.2 \nServer-side apps* of the Hippo Lab: [Integrate a React application with BloomReach Experience](https://www.onehippo.org/labs/integrate-a-react-application-with-bloomreach-experience.html).\n\n```jsx\nimport fetch from 'isomorphic-unfetch'\nimport { getApiUrl, CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\n// setting pageModel to empty list instead of null value,\n// as otherwise the API will be fetched client-side again after server-side fetch errors\nlet pageModel = {}\n\nconst request = { hostname: req.headers.host, path: asPath }\nconst url = getApiUrl(request, {})\n// pass cookies of initial request for CMS preview\nconst response = await fetch(url, {headers: {'Cookie': req.headers.cookie}})\n\nif (response.ok) {\n  try {\n    pageModel = await response.json()\n  } catch (err) {\n    console.log(`Error! Could not convert response to JSON for URL: ${url}`)\n  }\n} else {\n  console.log(`Error! Status code ${response.status} while fetching CMS page data for URL: ${url}`)\n}\n```  \n\n## Example React apps\n\nThere are two example React apps available that use the SDK. One client-side rendered, and one \nserver-side rendered using [Next.js](https://github.com/zeit/next.js). You can find the [example apps on \nGithub](https://github.com/bloomreach/experience-react-sdk/tree/master/examples).\n\n## Creating custom components\n\nAny components that are supplied through the `compenentDefinitions` prop can be any type of valid React \ncomponent, including functional components. Props are passed to these components as context so that you \ncan access the components' configuration, content, etc. See more information below.\n\n### Props\n\nThe following props are passed to a component that is rendered by `<RenderCmsComponent>`:\n- `configuration` - `Object` component configuration. Contains the contributed models, raw parameters \n and resolved parameters. Content included in the component's model is not serialized as part of the \n component's configuration but in a separate content object, and a JSON Pointer reference is used to \n link to the actual content object. This is done to prevent content from being included multiple times \n in the API response when referenced multiple times on a page. \n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview mode is active based on current URL supplied through \n `request` prop of `<CmsPage>`.\n\nFor more information on the Page Model API response, see the [Swagger documentation](https://www.onehippo.org/library/concepts/spa-plus/page-model-api/swagger-api-documentation.html).\n\n### Example\n\n```jsx\nimport React from 'react'\nimport NewsItem from './news-item'\nimport { getNestedObject } from 'bloomreach-experience-react-sdk'\n\nexport default class NewsList extends React.Component {\n  render() {\n    const preview = this.props.preview\n    const pageModel = this.props.pageModel\n    const configuration = this.props.configuration\n\n    // return placeholder if no list is set on component\n    const list = getNestedObject(configuration, ['models', 'pageable', 'items'])\n    if (!list && preview) {\n      return (<p>Click to configure {configuration.label}</p>)\n    } else if (!list) {\n      // don't render placeholder outside of preview mode\n      return null\n    }\n\n    // build list of news articles\n    const listItems = list.map((listItem, index) => {\n      if ('$ref' in listItem) {\n        return (<NewsItem contentRef={listItem.$ref} pageModel={pageModel} preview={preview} key={index}/>)\n      }\n    })\n\n    return (\n      <div className=\"row\">\n        <div className=\"col-sm-12 news-list\">\n          {listItems}\n        </div>\n      </div>\n    )\n  }\n}\n```\n\n### Content components\n\nComponents that reference a single content-item (e.g. the Banner component) can use a convenient \nwrapper-class that looks up the content and passes it as a prop. See below.\n\nTo enable this, the property `wrapInContentComponent: true` has to be set on the component in the \n`componentDefinitions` prop. See `componentDefinitions` in the API section for more details.\n\n#### Props\n\n- `content` - `Object` raw content object that contains the content-item's fields and field-values. Any \n references to other content-items (e.g. images) are serialized as JSON Pointers.\n- `manageContentButton` - `React.Component` for placement and rendering of the [Manage Content Button](https://www.onehippo.org/library/concepts/component-development/render-manage-content-button.html)\n in preview mode in CMS.\n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview is active based on current URL supplied through `request` \n prop of `<CmsPage>`.\n\n#### Example\n\n```jsx\nimport React from 'react'\n\nconst content = this.props.content;\nconst manageContentButton = this.props.manageContentButton;\n\nclass Banner extends React.Component {\n  render() {\n    return (\n      <div className=\"my-content-component\">\n        { manageContentButton && manageContentButton }\n        { content.title && content.title }\n      </div>)\n  }\n}\n```\n\n### Static CMS components\n\nStatic CMS components are components that are defined by developers / administrators and cannot be  \nmodified by users in the CMS. However, any content or site menus these components reference can be \nchanged by users in the CMS.\n\nSince `<RenderCmsComponent>` only renders container components (drag-and-drop components) by default, \nyou have to specify two additional properties in order to render a static CMS component: the `path` \nproperty to point to the relative path of the component, and `renderComponent` to specify which React \ncomponent to use for rendering the component. See the example below.\n\n```jsx\n<RenderCmsComponent path={'menu'} renderComponent={CmsMenu} />\n```\n\n### More component examples\n\nFor more detailed examples, see the components included in the [example applications](https://github.com/bloomreach/experience-react-sdk/tree/master/examples/client-side-rendered/src/components). \n\n### Helper functions\n\nAdditionally, there are a variety of helper functions available. See the examples below. For full \ndetails on the APIs, see the API section.\n\n```jsx\nimport { createLink, getImageUrl, getNestedObject, parseAndRewriteLinks, parseDate } from 'bloomreach-experience-react-sdk'\n\nconst link = createLink('ref', link, linkText, className)\nconst image = getImageUrl(content.image, this.props.pageModel, this.props.preview)\nconst list = getNestedObject(configuration, ['models', 'pageable', 'items', 0])\nconst contentHtml = parseAndRewriteLinks(content.content.value, this.props.preview)\nconst date = parseDate(content.date)\n```\n\n## API\n\n### `<CmsPage>`\n\nThe CmsPage component is a higher-order component that takes care of:\n- Fetching the Page Model for client-side rendering, when not supplied as a prop.\n- Fetching Page Model updates on component changes in the CMS.\n- Initializing and managing state, and providing this as context to `<RenderCmsComponent>`.\n\n#### Properties\n\n- `cmsUrls` - `Object` Override default CMS URL's. (Optional)\n- `componentDefinitions` - `object` Mapping of CMS catalog components to React components. Determines \n what component to render based from the Page Model. (Optional)\n- `createLink` - `Function` Called when creating internal links so that links can be constructed using \n the router library of the React app. (Optional)\n- `pageModel` - `Object` Supply Page Model as prop. Used for server-side-rendering where Page Model API \n is fetched server-side. When supplied, `CmsPage` will not fetch Page Model API on mount, only on \n component updates in CMS. (Optional)\n- `request` - `String` Current URL-path for determining if preview mode is active, and for fetching the \n Page Model for the page that is active. (Required)\n\n###### `cmsUrls` property\n\nProperty that allows you to override the default URL's for fetching the Page Model API. Typically you \nwill only have to define `scheme`, `hostname`, `port`, and `contextPath`. Input object takes the \nfollowing properties (all are optional):\n- `scheme` - `String` scheme (default: *http*)\n- `hostname` - `String` hostname (default: *localhost*)\n- `port` - `number` port number (default: *8080*)\n- `contextPath` - `String` site context-path (default: *site*)\n- `channelPath` - `String` path to the used channel, if channel is accessed through a subpath\n- `previewPrefix` - `String` preview-prefix used by CMS (default: *_cmsinternal*)\n- `apiPath` - `String` path to Page Model API as subpath (default: *resourceapi*)\n- `apiComponentRenderingUrlSuffix` - `String` (default: *?_hn:type=component-rendering&_hn:ref=*)\n\n###### `componentDefinitions` property\n\nMaps CMS catalog components to React components. Expects as input an object with `hst:label` of the CMS \ncomponents as keys and as value another object. The nested object has the mandatory property `component` \nwho's value maps the CMS component to a React component. See the example below:\n\n```js\nconst componentDefinitions = {\n  \"MyCustomCmsComponent\": { component: MyCustomReactComponent },\n  \"AnotherCmsComponent\": { component: AnotherReactComponent, wrapInContentComponent: true }\n};\n```\n\nAdditionally, the property `wrapInContentComponent: true` can be used for components that reference a \nsingle content-item. When this property is set on a component, it will be wrapped in a convenient \nwrapper class. See section *Content components*.\n\n##### `createLink` property\n\nCalled when creating internal links so that links can be constructed using the router library of the \nReact app. \n\nTakes `Function` as input. The function should return valid JSX and have three parameters:\n- `href` - `String` href of link\n- `linkText` - `Function` contains the HTML that is wrapped inside the link. Is a function so that it \n can include HTML.\n- `className` - `String` classnames to add to the link element\n\nFor example:\n```jsx\nconst createLink = (href, linkText, className) => {\n  return (<Link className={className} to={href}>{linkText()}</Link>)\n}\n```\n\n##### `pageModel` property\n\nPage Model can be supplied as a prop when using a server-side rendered / isomorphic React framework. \nWhen supplied, `<CmsPage>` will not fetch the Page Model API client-side. \n\n##### `request` property\n\nTakes `Object` as input with properties `hostname` and `path`, both of type `String`. The property \n`hostname` should contain the hostname for the current request (client-side this is \nwindow.location.hostname). The property `path` should contain the URL-path for the current request \n(client-side this is window.location.pathname);\n\n### `<RenderCmsComponent>`\n\nRenders a CMS component and all of its children using the Page Model supplied by `<CmsPage>`. Will \nrender the entire Page Model by default.\n\n#### Properties\n\n- `path` - `String` path to a component (static CMS component), container or container-item in the Page \n Model to render only that component and its children. If no path is supplied, entire Page Model will be \n rendered. \n- `renderComponent` - `React.Component` render a static CMS component using specified React component. \n Only works in combination with `path` property, which should specify path to the static CMS component. \n Site menus that are rendered this way can leverage the `<CmsEditButton>` component for rendering edit \n buttons in the CMS.\n\n#### Example\n\n```jsx\n<RenderCmsComponent path={'menu'} renderComponent={CmsMenu} />\n```\n\n### `<CmsEditButton>`\n\nInserts meta-data for either a content-item or site menu for placing an edit button in preview mode in \nthe CMS. Content-items that are rendered by a content component using `wrapInContentComponent: true` do \nnot need to use this component, but should use the `manageContentButton` prop that passes the meta-data.\n\n#### Properties\n\n- `configuration` - `Object` configuration of the site menu (not the component configuration containing \nthe menu) or the content-item object which has the `_meta` object in its root.\n- `preview` - `Boolean` toggle to prevent edit buttons from being rendered outside of preview.\n\n### `getApiUrl(request, [newCmsUrls])`\n\nHelper function for generating URL to the Page Model API for server-side fetching of the Page Model. \n\n#### Arguments\n\n- `request` - `Object` containing hostname and URL-path as properties `hostname` and `path` \n respectively. See the `request` property section above.\n- `newCmsUrls` - `Object` takes `cmsUrls` property as input to override default CMS URL's\n\n#### Return types\n\n`String` returns URL for fetching Page Model API\n\n### `createLink(linkType, link, linkText, className)`\n\nCreates a link to either a component or content-item itself or a referenced content-item (can be a \ndocument, image or asset) and returns the link as JSX.  \n\n#### Arguments\n\n- `linkType` - `String` type of link to create. Valid values are `self`, `ref` or `href`.\n  - `self` - Create link to the component or content-item itself. E.g. for a news-item in a news \n   overview.\n  - `ref` - Create link to a referenced content-item. E.g. for a banner.\n  - `href` -  Used by `parseAndRewriteLinks()` to create links using a href only.\n- `link` - `Object` the component configuration or content-object that is linking to itself or \n referenced another content-item.\n- `linkText` - `JSX | Function` HTML to wrap inside the link. Is a function so that it can include HTML.\n- `className` - `String` classnames to add to the link element\n\n#### Return types\n\n`JSX` returns link as JSX object that can be included as a variable anywhere within the return section \nof a React component's render method.\n\n### `getImageUrl(imageRef, pageModel, preview)`\n\nCreates link to URL of image in case BloomReach Experience is used for serving images.\n\n#### Arguments\n\n- `imageRef` - `String` JSON Pointer that references the image.\n- `pageModel` - `Object` since this function is a pure JavaScript function it can't get Page Model from \n context, so it has to be provided as function parameter. The Page Model is used to retrieve the image.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by \n `<RenderCmsComponent>` can pass the prop `this.props.preview`.\n\n#### Return types\n\n`String` returns URL to image.\n\n### `getNestedObject(nestedObject, pathArray)`\n\nReturns a nested object or value using a path array. Useful when you need to access deeply nested \nobjects/values without having to string null checks together.\n\n#### Arguments\n\n- `nestedObject` - `Object` the object containing the nested object or value.\n- `pathArray` - `Array` contains the path to the nested object as an array.\n\n#### Return types\n\n`Object|null` returns the nested object if found, otherwise returns null. \n\n### `parseAndRewriteLinks(html, preview)`\n\nParses HTML of a rich-text field of a content-item for rewriting links in HTML to internal links. Uses \nthe `createLink` function passed to `<CmsPage>` for constructing internal links.\n\n#### Arguments\n\n- `html` - `String` value of rich-text field of a content-item. Should contain HTML only.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by \n `<RenderCmsComponent>` can pass the prop `this.props.preview`.\n\n#### Return types\n\n`JSX` returns parsed and rewrited HTML as JSX.\n\n### `parseDate(date)`\n\nParses date-field of a content item and returns date as a string.\n\n#### Arguments\n\n- `date` - `String` takes raw value of a date-field as input, following the ISO 8601:2000 format.\n\n#### Return types\n\n`String` returns date in full date format.\n\n## Release notes\n\n### Version 0.4.0\n\nAdded support for rendering static CMS components.\n- Added new property `renderComponent` to `<RenderCmsComponent>` which allows you to render a static \n component. This only works in combination with the `path` property, which should contain the relative \n path to the component.\n- Renamed `<ManageContentButton>` to `<CmsEditButton>` and exported it so it can be used by apps. This \n component is now more generic so it can also be used to generate edit buttons in the CMS for site menus.\n- Moved `<CmsMenu>` component out of SDK and into the example apps.\n\n\n### Version 0.3.0\n\nAdded extra checks so that `<div>` elements needed for CMS preview are only inserted in preview mode.\n\n### Version 0.2.0\n\nThis version includes significant changes. Please make sure to update your components using the upgrade \nsteps further down.\n- Changed `cmsUrls` property to support different live and preview URLs.\n- Changed `urlPath` property to `request` property which no longer takes URL-path as string, but an \n object with hostname and URL-path. This property should be passed to `<CmsPage>`.\n- Changed helper method `getApiUrl()` to take `request` property as parameter instead of `urlPath`.\n- Changed helper method `parseAndRewriteLinks()` to take an extra parameter: `preview`.\n- Changed helper method `getImageUrl()` to take an extra parameter: `preview`.\n\nUpgrade steps:\n- Modify `cmsUrls` property to include URLs for live and preview using the properties `live` and \n `preview` respectively. Please note that the `cms` prefix has been removed from all URL properties. So `cmsHostname` has become `hostname`. Preview URLs are optional. For example:\n  ```js\n  const cmsUrls = {\n    live: {\n      hostname: bloomreach.com\n    },\n    preview: {\n      hostname: cms.bloomreach.com\n    }\n  }\n  ```\n- Pass current request details through `request` property to `<CmsPage>`. This was previously done \n through the `urlPath` property. The `request` property should be an object that contains the hostname \n and path as properties `hostname` and `path` respectively. For example:\n  ```jsx\n  const request = { hostname: window.location.hostname, path: window.location.path };\n  <CmsPage componentDefinitions={componentDefinitions} request={request}>\n  ```\n- Update usage of `getApiUrl` to pass `request` property (see previous bullet) instead of URL-path.\n- Update usage of helper methods `getImageUrl()` and `parseAndRewriteLinks()` to include the preview \n parameter. Components rendered by `<RenderCmsComponent>` have the preview value passed as prop \n `this.props.preview`.\n\n## FAQ / Troubleshooting\n\nNothing here yet :)\n\n## Author\n\nRobbert Kauffman - BloomReach\n","gitHead":"24fa075274fa5f392e300f7dda07974f9e7e4859","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"rkauffman","email":"robbertkauffman@gmail.com"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.2.0","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.8.0","dependencies":{"jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.4.3-rc1_1538238617060_0.5883337710637404","host":"s3://npm-registry-packages"}},"0.4.4-rc1":{"name":"bloomreach-experience-react-sdk","version":"0.4.4-rc1","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.4.4-rc1","maintainers":[{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"9f0da49499fc146e46beaf9109717c13812f340f","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.4.4-rc1.tgz","fileCount":27,"integrity":"sha512-s7zfOZaiEUnGOwFvDOO9vBei3JAY5bATXnW0IW7WmtcKSQ2Q4YC3R4ZrqGPsbjDXcUut+REZR0JZbYmOJ0wjaQ==","signatures":[{"sig":"MEQCIDSwPmpUwFsxZcXEFqQs4MNE9fY3A/nBCEKe/11oCdxPAiBbQ2ma3FYUf6nM9De+fAcNCG+QS0Jc8rUS9eLpbI3kCw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":241874,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbtX/VCRA9TVsSAnZWagAAuzUP/3SYHMx4tPY4YJXplM1p\nogkl8C3ELO08axXIKsLUBhvVSHERwGvJCHhYSsmFVTMjCwatBfl9kF3Qb/cM\nZ8vUpx0vu3x6pKRddqLcvsBFlut6oXjkNIBZQR3aUjYRcCO/v20eGBU8CyUl\nlw7wgBBrPxpInZ5aSrJmZxmnNC30qyN79Ia3wBPuiJm3zkFaf6JBhsEcgCMn\nkChC+8D4JdBS0kGNEaWQYroEzAH8tq/XBp0+Uu2O9kMPwZ7/LELYpMH9id9b\nbWHCDyMCTl7fvXgDiNy7txXdbE9mKowpxkQ6Kl+ny6m2gIRb74iiDR6Q1Gqm\nBVFeVuT+zsIyAXL0gQkhLSeXbvuVEsqkwSj4vUav0ffio+eE5nACsB2sY5tc\nceaTv6Z6Qx4dbsqCremvfdgtf+t1/GIWHK/gx53EycqkM3tW8A9/uqqsNzFI\nhCcj8tcz56ZCS1I2leh1muCLqK/jW9WfGnMlRSjHtVHklIXktC1lFMsqT74L\n5q6bDgWS3vyrk0iN6ehsQEE+2PYm37f9A3ekCTw4hV77QA0o53887HBmmO5f\nOlORO1cW3998bb5JoLD6wrhS2l833YHZ3izC8/Arzlw9pDGYe5hECpPGYANC\n/lc6RHaIAzJax1peCFIa9sXumwGkAWPbQTT8wgHgS7dRY9UlYFjPO55GXmP1\n5rwD\r\n=WhnD\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","readme":"# BloomReach Experience SDK for React\n\nSDK for powering content and components in React applications by [BloomReach Experience](https://www.bloomreach.com/en/products/experience). \nThis library makes integrating a React app with BloomReach Experience a breeze. It supports both \nclient-side- and server-side rendered/isomorphic React apps. \n\nBloomReach Experience allows you to use an external front-end such as React for rendering while still \nproviding a native-like authoring experience, such as integrated preview, in-context editing, drag & \ndrop, server-side personalization. For more information on this approach, see [A new approach to \nintegrating SPA's with WCM: Fixing what's wrong with headless integrations](https://www.bloomreach.com/en/blog/2018/03/a-new-approach-to-integrating-spas-with-wcm-fixing-what%E2%80%99s-wrong-with-headless-integrations.html).\n\n## Install\n\n```bash\nnpm install --save bloomreach-experience-react-sdk\n```\n\n## Usage\n\n```jsx\nimport React from 'react'\nimport { CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\nconst componentDefinitions = {\n  \"MyCustomComponent\": { component: MyCustomComponent }\n}\n\nclass MyApp extends React.Component {\n  render() {\n    const request = { hostname: window.location.hostname, path: window.location.pathname };\n    return (\n      <CmsPage componentDefinitions={componentDefinitions} request={request}>\n        { () =>\n          <RenderCmsComponent />\n        }\n      </CmsPage>\n    )\n  }\n}\n```\n\nAt a minimum, `<CmsPage>` and `<RenderCmsComponent>` should be imported in the React app.\n\n`<CmsPage>` fetches the Page Model when it is not supplied as a prop (see section on server-side \nrendering); it fetches updates to the page model on component changes in the CMS; and it initializes and \nmanages state, and provides this as context to `<RenderCmsComponent>`. The `<CmsPage>` component can be \nput anywhere within the React App.\n\n`<RenderCmsComponent>` renders components based on the Page Model API response. It consumes the state \nfrom `<CmsPage>` and renders the container components and any content referenced from the components as \ncontained in the Page Model API response. The `<RenderCmsComponent>` should be nested within `<CmsPage>` \nand placed in the React app at the exact location where you want BloomReach Experience to control what \ncomponents and content is rendered.\n\nPlease note that `<CmsPage>` takes children as a function instead of as a prop, because it is not \npossible to provide state through context providers due to a bug in React currently. So make sure to \nwrap any children of `<CmsPage>` in a function, as in the following example:\n\n ```jsx\n{ () =>\n  // any children go here\n  <h1>Blooming is what I do</h1>\n}\n ```\n\n`<CmsPage>` takes two props: `componentDefinitions` and `request`.\n\nThe `request` prop is used to fetch the Page Model for the current page; and to detect whether \npreview mode is active so that meta-data for Channel Manager functionality (e.g. in-context editing) is \nincluded in the HTML, and consequently Channel Manager functionality is enabled.\n\nFinally, component definitions are supplied through the `componentDefinitions` prop. The component \ndefinitions tell `<RenderCmsComponent>` what React component to render by mapping these to the \n*hst:label* of a CMS catalog component.\n\n## Server-side rendering\n\nFor server-side rendering (e.g. using [Next.js](https://github.com/zeit/next.js)) you need to fetch the \nPage Model API server-side and supply it as a prop to `<CmsPage>`. Apart from this the usage is the same \nas with client-side rendering.\n\nThe helper function `getApiUrl()` can be used to generate the Page Model API URL using the current \nrequest.\n\nIt is important to pass cookies from the initial request and supply these with the request header of the \nPage Model API request. Otherwise you will get a 403 error in preview mode.\n\nFinally, to get preview to work for server-side rendered apps you can use a reverse proxy to route \nrequests from BloomReach's site preview to the React App-server. For more details, see section *3.2 \nServer-side apps* of the Hippo Lab: [Integrate a React application with BloomReach Experience](https://www.onehippo.org/labs/integrate-a-react-application-with-bloomreach-experience.html).\n\n```jsx\nimport fetch from 'isomorphic-unfetch'\nimport { getApiUrl, CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\n// setting pageModel to empty list instead of null value,\n// as otherwise the API will be fetched client-side again after server-side fetch errors\nlet pageModel = {}\n\nconst request = { hostname: req.headers.host, path: asPath }\nconst url = getApiUrl(request, {})\n// pass cookies of initial request for CMS preview\nconst response = await fetch(url, {headers: {'Cookie': req.headers.cookie}})\n\nif (response.ok) {\n  try {\n    pageModel = await response.json()\n  } catch (err) {\n    console.log(`Error! Could not convert response to JSON for URL: ${url}`)\n  }\n} else {\n  console.log(`Error! Status code ${response.status} while fetching CMS page data for URL: ${url}`)\n}\n```  \n\n## Example React apps\n\nThere are two example React apps available that use the SDK. One client-side rendered, and one \nserver-side rendered using [Next.js](https://github.com/zeit/next.js). You can find the [example apps on \nGithub](https://github.com/bloomreach/experience-react-sdk/tree/master/examples).\n\n## Creating custom components\n\nAny components that are supplied through the `compenentDefinitions` prop can be any type of valid React \ncomponent, including functional components. Props are passed to these components as context so that you \ncan access the components' configuration, content, etc. See more information below.\n\n### Props\n\nThe following props are passed to a component that is rendered by `<RenderCmsComponent>`:\n- `configuration` - `Object` component configuration. Contains the contributed models, raw parameters \n and resolved parameters. Content included in the component's model is not serialized as part of the \n component's configuration but in a separate content object, and a JSON Pointer reference is used to \n link to the actual content object. This is done to prevent content from being included multiple times \n in the API response when referenced multiple times on a page. \n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview mode is active based on current URL supplied through \n `request` prop of `<CmsPage>`.\n\nFor more information on the Page Model API response, see the [Swagger documentation](https://www.onehippo.org/library/concepts/spa-plus/page-model-api/swagger-api-documentation.html).\n\n### Example\n\n```jsx\nimport React from 'react'\nimport NewsItem from './news-item'\nimport { getNestedObject } from 'bloomreach-experience-react-sdk'\n\nexport default class NewsList extends React.Component {\n  render() {\n    const preview = this.props.preview\n    const pageModel = this.props.pageModel\n    const configuration = this.props.configuration\n\n    // return placeholder if no list is set on component\n    const list = getNestedObject(configuration, ['models', 'pageable', 'items'])\n    if (!list && preview) {\n      return (<p>Click to configure {configuration.label}</p>)\n    } else if (!list) {\n      // don't render placeholder outside of preview mode\n      return null\n    }\n\n    // build list of news articles\n    const listItems = list.map((listItem, index) => {\n      if ('$ref' in listItem) {\n        return (<NewsItem contentRef={listItem.$ref} pageModel={pageModel} preview={preview} key={index}/>)\n      }\n    })\n\n    return (\n      <div className=\"row\">\n        <div className=\"col-sm-12 news-list\">\n          {listItems}\n        </div>\n      </div>\n    )\n  }\n}\n```\n\n### Content components\n\nComponents that reference a single content-item (e.g. the Banner component) can use a convenient \nwrapper-class that looks up the content and passes it as a prop. See below.\n\nTo enable this, the property `wrapInContentComponent: true` has to be set on the component in the \n`componentDefinitions` prop. See `componentDefinitions` in the API section for more details.\n\n#### Props\n\n- `content` - `Object` raw content object that contains the content-item's fields and field-values. Any \n references to other content-items (e.g. images) are serialized as JSON Pointers.\n- `manageContentButton` - `React.Component` for placement and rendering of the [Manage Content Button](https://www.onehippo.org/library/concepts/component-development/render-manage-content-button.html)\n in preview mode in CMS.\n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview is active based on current URL supplied through `request` \n prop of `<CmsPage>`.\n\n#### Example\n\n```jsx\nimport React from 'react'\n\nconst content = this.props.content;\nconst manageContentButton = this.props.manageContentButton;\n\nclass Banner extends React.Component {\n  render() {\n    return (\n      <div className=\"my-content-component\">\n        { manageContentButton && manageContentButton }\n        { content.title && content.title }\n      </div>)\n  }\n}\n```\n\n### Static CMS components\n\nStatic CMS components are components that are defined by developers / administrators and cannot be  \nmodified by users in the CMS. However, any content or site menus these components reference can be \nchanged by users in the CMS.\n\nSince `<RenderCmsComponent>` only renders container components (drag-and-drop components) by default, \nyou have to specify two additional properties in order to render a static CMS component: the `path` \nproperty to point to the relative path of the component, and `renderComponent` to specify which React \ncomponent to use for rendering the component. See the example below.\n\n```jsx\n<RenderCmsComponent path={'menu'} renderComponent={CmsMenu} />\n```\n\n### More component examples\n\nFor more detailed examples, see the components included in the [example applications](https://github.com/bloomreach/experience-react-sdk/tree/master/examples/client-side-rendered/src/components). \n\n### Helper functions\n\nAdditionally, there are a variety of helper functions available. See the examples below. For full \ndetails on the APIs, see the API section.\n\n```jsx\nimport { createLink, getImageUrl, getNestedObject, parseAndRewriteLinks, parseDate } from 'bloomreach-experience-react-sdk'\n\nconst link = createLink('ref', link, linkText, className)\nconst image = getImageUrl(content.image, this.props.pageModel, this.props.preview)\nconst list = getNestedObject(configuration, ['models', 'pageable', 'items', 0])\nconst contentHtml = parseAndRewriteLinks(content.content.value, this.props.preview)\nconst date = parseDate(content.date)\n```\n\n## API\n\n### `<CmsPage>`\n\nThe CmsPage component is a higher-order component that takes care of:\n- Fetching the Page Model for client-side rendering, when not supplied as a prop.\n- Fetching Page Model updates on component changes in the CMS.\n- Initializing and managing state, and providing this as context to `<RenderCmsComponent>`.\n\n#### Properties\n\n- `cmsUrls` - `Object` Override default CMS URL's. (Optional)\n- `componentDefinitions` - `object` Mapping of CMS catalog components to React components. Determines \n what component to render based from the Page Model. (Optional)\n- `createLink` - `Function` Called when creating internal links so that links can be constructed using \n the router library of the React app. (Optional)\n- `pageModel` - `Object` Supply Page Model as prop. Used for server-side-rendering where Page Model API \n is fetched server-side. When supplied, `CmsPage` will not fetch Page Model API on mount, only on \n component updates in CMS. (Optional)\n- `request` - `String` Current URL-path for determining if preview mode is active, and for fetching the \n Page Model for the page that is active. (Required)\n\n###### `cmsUrls` property\n\nProperty that allows you to override the default URL's for fetching the Page Model API. Typically you \nwill only have to define `scheme`, `hostname`, `port`, and `contextPath`. Input object takes the \nfollowing properties (all are optional):\n- `scheme` - `String` scheme (default: *http*)\n- `hostname` - `String` hostname (default: *localhost*)\n- `port` - `number` port number (default: *8080*)\n- `contextPath` - `String` site context-path (default: *site*)\n- `channelPath` - `String` path to the used channel, if channel is accessed through a subpath\n- `previewPrefix` - `String` preview-prefix used by CMS (default: *_cmsinternal*)\n- `apiPath` - `String` path to Page Model API as subpath (default: *resourceapi*)\n- `apiComponentRenderingUrlSuffix` - `String` (default: *?_hn:type=component-rendering&_hn:ref=*)\n\n###### `componentDefinitions` property\n\nMaps CMS catalog components to React components. Expects as input an object with `hst:label` of the CMS \ncomponents as keys and as value another object. The nested object has the mandatory property `component` \nwho's value maps the CMS component to a React component. See the example below:\n\n```js\nconst componentDefinitions = {\n  \"MyCustomCmsComponent\": { component: MyCustomReactComponent },\n  \"AnotherCmsComponent\": { component: AnotherReactComponent, wrapInContentComponent: true }\n};\n```\n\nAdditionally, the property `wrapInContentComponent: true` can be used for components that reference a \nsingle content-item. When this property is set on a component, it will be wrapped in a convenient \nwrapper class. See section *Content components*.\n\n##### `createLink` property\n\nCalled when creating internal links so that links can be constructed using the router library of the \nReact app. \n\nTakes `Function` as input. The function should return valid JSX and have three parameters:\n- `href` - `String` href of link\n- `linkText` - `Function` contains the HTML that is wrapped inside the link. Is a function so that it \n can include HTML.\n- `className` - `String` classnames to add to the link element\n\nFor example:\n```jsx\nconst createLink = (href, linkText, className) => {\n  return (<Link className={className} to={href}>{linkText()}</Link>)\n}\n```\n\n##### `pageModel` property\n\nPage Model can be supplied as a prop when using a server-side rendered / isomorphic React framework. \nWhen supplied, `<CmsPage>` will not fetch the Page Model API client-side. \n\n##### `request` property\n\nTakes `Object` as input with properties `hostname` and `path`, both of type `String`. The property \n`hostname` should contain the hostname for the current request (client-side this is \nwindow.location.hostname). The property `path` should contain the URL-path for the current request \n(client-side this is window.location.pathname);\n\n### `<RenderCmsComponent>`\n\nRenders a CMS component and all of its children using the Page Model supplied by `<CmsPage>`. Will \nrender the entire Page Model by default.\n\n#### Properties\n\n- `path` - `String` path to a component (static CMS component), container or container-item in the Page \n Model to render only that component and its children. If no path is supplied, entire Page Model will be \n rendered. \n- `renderComponent` - `React.Component` render a static CMS component using specified React component. \n Only works in combination with `path` property, which should specify path to the static CMS component. \n Site menus that are rendered this way can leverage the `<CmsEditButton>` component for rendering edit \n buttons in the CMS.\n\n#### Example\n\n```jsx\n<RenderCmsComponent path={'menu'} renderComponent={CmsMenu} />\n```\n\n### `<CmsEditButton>`\n\nInserts meta-data for either a content-item or site menu for placing an edit button in preview mode in \nthe CMS. Content-items that are rendered by a content component using `wrapInContentComponent: true` do \nnot need to use this component, but should use the `manageContentButton` prop that passes the meta-data.\n\n#### Properties\n\n- `configuration` - `Object` configuration of the site menu (not the component configuration containing \nthe menu) or the content-item object which has the `_meta` object in its root.\n- `preview` - `Boolean` toggle to prevent edit buttons from being rendered outside of preview.\n\n### `getApiUrl(request, [newCmsUrls])`\n\nHelper function for generating URL to the Page Model API for server-side fetching of the Page Model. \n\n#### Arguments\n\n- `request` - `Object` containing hostname and URL-path as properties `hostname` and `path` \n respectively. See the `request` property section above.\n- `newCmsUrls` - `Object` takes `cmsUrls` property as input to override default CMS URL's\n\n#### Return types\n\n`String` returns URL for fetching Page Model API\n\n### `createLink(linkType, link, linkText, className)`\n\nCreates a link to either a component or content-item itself or a referenced content-item (can be a \ndocument, image or asset) and returns the link as JSX.  \n\n#### Arguments\n\n- `linkType` - `String` type of link to create. Valid values are `self`, `ref` or `href`.\n  - `self` - Create link to the component or content-item itself. E.g. for a news-item in a news \n   overview.\n  - `ref` - Create link to a referenced content-item. E.g. for a banner.\n  - `href` -  Used by `parseAndRewriteLinks()` to create links using a href only.\n- `link` - `Object` the component configuration or content-object that is linking to itself or \n referenced another content-item.\n- `linkText` - `JSX | Function` HTML to wrap inside the link. Is a function so that it can include HTML.\n- `className` - `String` classnames to add to the link element\n\n#### Return types\n\n`JSX` returns link as JSX object that can be included as a variable anywhere within the return section \nof a React component's render method.\n\n### `getImageUrl(imageRef, pageModel, preview)`\n\nCreates link to URL of image in case BloomReach Experience is used for serving images.\n\n#### Arguments\n\n- `imageRef` - `String` JSON Pointer that references the image.\n- `pageModel` - `Object` since this function is a pure JavaScript function it can't get Page Model from \n context, so it has to be provided as function parameter. The Page Model is used to retrieve the image.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by \n `<RenderCmsComponent>` can pass the prop `this.props.preview`.\n\n#### Return types\n\n`String` returns URL to image.\n\n### `getNestedObject(nestedObject, pathArray)`\n\nReturns a nested object or value using a path array. Useful when you need to access deeply nested \nobjects/values without having to string null checks together.\n\n#### Arguments\n\n- `nestedObject` - `Object` the object containing the nested object or value.\n- `pathArray` - `Array` contains the path to the nested object as an array.\n\n#### Return types\n\n`Object|null` returns the nested object if found, otherwise returns null. \n\n### `parseAndRewriteLinks(html, preview)`\n\nParses HTML of a rich-text field of a content-item for rewriting links in HTML to internal links. Uses \nthe `createLink` function passed to `<CmsPage>` for constructing internal links.\n\n#### Arguments\n\n- `html` - `String` value of rich-text field of a content-item. Should contain HTML only.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by \n `<RenderCmsComponent>` can pass the prop `this.props.preview`.\n\n#### Return types\n\n`JSX` returns parsed and rewrited HTML as JSX.\n\n### `parseDate(date)`\n\nParses date-field of a content item and returns date as a string.\n\n#### Arguments\n\n- `date` - `String` takes raw value of a date-field as input, following the ISO 8601:2000 format.\n\n#### Return types\n\n`String` returns date in full date format.\n\n## Release notes\n\n### Version 0.4.0\n\nAdded support for rendering static CMS components.\n- Added new property `renderComponent` to `<RenderCmsComponent>` which allows you to render a static \n component. This only works in combination with the `path` property, which should contain the relative \n path to the component.\n- Renamed `<ManageContentButton>` to `<CmsEditButton>` and exported it so it can be used by apps. This \n component is now more generic so it can also be used to generate edit buttons in the CMS for site menus.\n- Moved `<CmsMenu>` component out of SDK and into the example apps.\n\n\n### Version 0.3.0\n\nAdded extra checks so that `<div>` elements needed for CMS preview are only inserted in preview mode.\n\n### Version 0.2.0\n\nThis version includes significant changes. Please make sure to update your components using the upgrade \nsteps further down.\n- Changed `cmsUrls` property to support different live and preview URLs.\n- Changed `urlPath` property to `request` property which no longer takes URL-path as string, but an \n object with hostname and URL-path. This property should be passed to `<CmsPage>`.\n- Changed helper method `getApiUrl()` to take `request` property as parameter instead of `urlPath`.\n- Changed helper method `parseAndRewriteLinks()` to take an extra parameter: `preview`.\n- Changed helper method `getImageUrl()` to take an extra parameter: `preview`.\n\nUpgrade steps:\n- Modify `cmsUrls` property to include URLs for live and preview using the properties `live` and \n `preview` respectively. Please note that the `cms` prefix has been removed from all URL properties. So `cmsHostname` has become `hostname`. Preview URLs are optional. For example:\n  ```js\n  const cmsUrls = {\n    live: {\n      hostname: bloomreach.com\n    },\n    preview: {\n      hostname: cms.bloomreach.com\n    }\n  }\n  ```\n- Pass current request details through `request` property to `<CmsPage>`. This was previously done \n through the `urlPath` property. The `request` property should be an object that contains the hostname \n and path as properties `hostname` and `path` respectively. For example:\n  ```jsx\n  const request = { hostname: window.location.hostname, path: window.location.path };\n  <CmsPage componentDefinitions={componentDefinitions} request={request}>\n  ```\n- Update usage of `getApiUrl` to pass `request` property (see previous bullet) instead of URL-path.\n- Update usage of helper methods `getImageUrl()` and `parseAndRewriteLinks()` to include the preview \n parameter. Components rendered by `<RenderCmsComponent>` have the preview value passed as prop \n `this.props.preview`.\n\n## FAQ / Troubleshooting\n\nNothing here yet :)\n\n## Author\n\nRobbert Kauffman - BloomReach\n","gitHead":"5fb4c445c0dcab3d6a81fac8c864afa894078bec","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"rkauffman","email":"robbertkauffman@gmail.com"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.4.1","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.11.0","dependencies":{"jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.4.4-rc1_1538621396764_0.7915373224011191","host":"s3://npm-registry-packages"}},"0.4.5-rc1":{"name":"bloomreach-experience-react-sdk","version":"0.4.5-rc1","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.4.5-rc1","maintainers":[{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"09694ce7fd35078b46404ae92d76862959208f54","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.4.5-rc1.tgz","fileCount":27,"integrity":"sha512-Gx0FubdjydzK5RY//wEQ6ZgGaLIfmmj9UucVBm2W19VlR9lVswOdt3LE2iUyqByD6urEoVMlMhRZSv4PYkgF7w==","signatures":[{"sig":"MEYCIQDN1gPjAbVyT3NSadmB3xR7RE02HRwXEPRsYpioD+e8hQIhAMVcdZ3M+JFdsYLvKefTX40GhV0OqJPZU1jqKgEgGJMB","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":241895,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbvlqGCRA9TVsSAnZWagAAndUP/Amy/QWD0fIgS7qDQH5U\nQ9cDLKTaaZEQrtbcuRtq0eKNDVP+rBuF/a28nX5dDv24CVrXGQw5t6aqTc/o\noT2hwmHXtfnVchYYuV1AKHjgOyRTQOjLwRDxzYMn6Y2TSTujAD9DNBrxGoDq\nd6PFgU3o6FKI9DbklE1HHyvdV1y0g50vIEWIKOnR1Do+00ZkdWwkVyXATUpX\nIb7Z7UoKN7dH9Z+MTbwkwKpkJ4cepL8NgIZQbtZe+6EaN+ASu9Su8Zsk66+u\nI+Crqgt8alIcq/sIeZJJ3pyNkBAE/CITMR21Q25q9G78Qv15ohKpRjN3NYtd\n5B08LNyz42xytBNBUckcRdDWchpjqMa3fF08ZG+D+ixjgvFAtdf56rwd6O6h\n8yeoiLjKyYyAJTJuC2yb/lrVSE4ozOEhoJ7Z+F6lqgrJuM+g1lEdvmUqOQvS\nbr5XqbtNUYfstXZfGZMO9hXQk4RyWyTh82MzijzMl5RzridsBelKXZiHYtWr\nLxno2TCqPLZyWckTpiA7MVPDCDcKDe7a/HInxf27hNZk/wJ+ZxJa8NE9E093\nopXYo7rYktSQeGpUuU+qoi/FUWoaA5hMTz3P90YgL6fjXZuwVXhbuETjMjfA\ne4qvhdDSKdWN8CB/UkAe1HDhokktcHgxDuezFl1MRRPmlOWXfyXbj9dSMtxF\n+cI0\r\n=yJjC\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","readme":"# BloomReach Experience SDK for React\n\nSDK for powering content and components in React applications by [BloomReach Experience](https://www.bloomreach.com/en/products/experience). \nThis library makes integrating a React app with BloomReach Experience a breeze. It supports both \nclient-side- and server-side rendered/isomorphic React apps. \n\nBloomReach Experience allows you to use an external front-end such as React for rendering while still \nproviding a native-like authoring experience, such as integrated preview, in-context editing, drag & \ndrop, server-side personalization. For more information on this approach, see [A new approach to \nintegrating SPA's with WCM: Fixing what's wrong with headless integrations](https://www.bloomreach.com/en/blog/2018/03/a-new-approach-to-integrating-spas-with-wcm-fixing-what%E2%80%99s-wrong-with-headless-integrations.html).\n\n## Install\n\n```bash\nnpm install --save bloomreach-experience-react-sdk\n```\n\n## Usage\n\n```jsx\nimport React from 'react'\nimport { CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\nconst componentDefinitions = {\n  \"MyCustomComponent\": { component: MyCustomComponent }\n}\n\nclass MyApp extends React.Component {\n  render() {\n    const request = { hostname: window.location.hostname, path: window.location.pathname };\n    return (\n      <CmsPage componentDefinitions={componentDefinitions} request={request}>\n        { () =>\n          <RenderCmsComponent />\n        }\n      </CmsPage>\n    )\n  }\n}\n```\n\nAt a minimum, `<CmsPage>` and `<RenderCmsComponent>` should be imported in the React app.\n\n`<CmsPage>` fetches the Page Model when it is not supplied as a prop (see section on server-side \nrendering); it fetches updates to the page model on component changes in the CMS; and it initializes and \nmanages state, and provides this as context to `<RenderCmsComponent>`. The `<CmsPage>` component can be \nput anywhere within the React App.\n\n`<RenderCmsComponent>` renders components based on the Page Model API response. It consumes the state \nfrom `<CmsPage>` and renders the container components and any content referenced from the components as \ncontained in the Page Model API response. The `<RenderCmsComponent>` should be nested within `<CmsPage>` \nand placed in the React app at the exact location where you want BloomReach Experience to control what \ncomponents and content is rendered.\n\nPlease note that `<CmsPage>` takes children as a function instead of as a prop, because it is not \npossible to provide state through context providers due to a bug in React currently. So make sure to \nwrap any children of `<CmsPage>` in a function, as in the following example:\n\n ```jsx\n{ () =>\n  // any children go here\n  <h1>Blooming is what I do</h1>\n}\n ```\n\n`<CmsPage>` takes two props: `componentDefinitions` and `request`.\n\nThe `request` prop is used to fetch the Page Model for the current page; and to detect whether \npreview mode is active so that meta-data for Channel Manager functionality (e.g. in-context editing) is \nincluded in the HTML, and consequently Channel Manager functionality is enabled.\n\nFinally, component definitions are supplied through the `componentDefinitions` prop. The component \ndefinitions tell `<RenderCmsComponent>` what React component to render by mapping these to the \n*hst:label* of a CMS catalog component.\n\n## Server-side rendering\n\nFor server-side rendering (e.g. using [Next.js](https://github.com/zeit/next.js)) you need to fetch the \nPage Model API server-side and supply it as a prop to `<CmsPage>`. Apart from this the usage is the same \nas with client-side rendering.\n\nThe helper function `getApiUrl()` can be used to generate the Page Model API URL using the current \nrequest.\n\nIt is important to pass cookies from the initial request and supply these with the request header of the \nPage Model API request. Otherwise you will get a 403 error in preview mode.\n\nFinally, to get preview to work for server-side rendered apps you can use a reverse proxy to route \nrequests from BloomReach's site preview to the React App-server. For more details, see section *3.2 \nServer-side apps* of the Hippo Lab: [Integrate a React application with BloomReach Experience](https://www.onehippo.org/labs/integrate-a-react-application-with-bloomreach-experience.html).\n\n```jsx\nimport fetch from 'isomorphic-unfetch'\nimport { getApiUrl, CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\n// setting pageModel to empty list instead of null value,\n// as otherwise the API will be fetched client-side again after server-side fetch errors\nlet pageModel = {}\n\nconst request = { hostname: req.headers.host, path: asPath }\nconst url = getApiUrl(request, {})\n// pass cookies of initial request for CMS preview\nconst response = await fetch(url, {headers: {'Cookie': req.headers.cookie}})\n\nif (response.ok) {\n  try {\n    pageModel = await response.json()\n  } catch (err) {\n    console.log(`Error! Could not convert response to JSON for URL: ${url}`)\n  }\n} else {\n  console.log(`Error! Status code ${response.status} while fetching CMS page data for URL: ${url}`)\n}\n```  \n\n## Example React apps\n\nThere are two example React apps available that use the SDK. One client-side rendered, and one \nserver-side rendered using [Next.js](https://github.com/zeit/next.js). You can find the [example apps on \nGithub](https://github.com/bloomreach/experience-react-sdk/tree/master/examples).\n\n## Creating custom components\n\nAny components that are supplied through the `compenentDefinitions` prop can be any type of valid React \ncomponent, including functional components. Props are passed to these components as context so that you \ncan access the components' configuration, content, etc. See more information below.\n\n### Props\n\nThe following props are passed to a component that is rendered by `<RenderCmsComponent>`:\n- `configuration` - `Object` component configuration. Contains the contributed models, raw parameters \n and resolved parameters. Content included in the component's model is not serialized as part of the \n component's configuration but in a separate content object, and a JSON Pointer reference is used to \n link to the actual content object. This is done to prevent content from being included multiple times \n in the API response when referenced multiple times on a page. \n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview mode is active based on current URL supplied through \n `request` prop of `<CmsPage>`.\n\nFor more information on the Page Model API response, see the [Swagger documentation](https://www.onehippo.org/library/concepts/spa-plus/page-model-api/swagger-api-documentation.html).\n\n### Example\n\n```jsx\nimport React from 'react'\nimport NewsItem from './news-item'\nimport { getNestedObject } from 'bloomreach-experience-react-sdk'\n\nexport default class NewsList extends React.Component {\n  render() {\n    const preview = this.props.preview\n    const pageModel = this.props.pageModel\n    const configuration = this.props.configuration\n\n    // return placeholder if no list is set on component\n    const list = getNestedObject(configuration, ['models', 'pageable', 'items'])\n    if (!list && preview) {\n      return (<p>Click to configure {configuration.label}</p>)\n    } else if (!list) {\n      // don't render placeholder outside of preview mode\n      return null\n    }\n\n    // build list of news articles\n    const listItems = list.map((listItem, index) => {\n      if ('$ref' in listItem) {\n        return (<NewsItem contentRef={listItem.$ref} pageModel={pageModel} preview={preview} key={index}/>)\n      }\n    })\n\n    return (\n      <div className=\"row\">\n        <div className=\"col-sm-12 news-list\">\n          {listItems}\n        </div>\n      </div>\n    )\n  }\n}\n```\n\n### Content components\n\nComponents that reference a single content-item (e.g. the Banner component) can use a convenient \nwrapper-class that looks up the content and passes it as a prop. See below.\n\nTo enable this, the property `wrapInContentComponent: true` has to be set on the component in the \n`componentDefinitions` prop. See `componentDefinitions` in the API section for more details.\n\n#### Props\n\n- `content` - `Object` raw content object that contains the content-item's fields and field-values. Any \n references to other content-items (e.g. images) are serialized as JSON Pointers.\n- `manageContentButton` - `React.Component` for placement and rendering of the [Manage Content Button](https://www.onehippo.org/library/concepts/component-development/render-manage-content-button.html)\n in preview mode in CMS.\n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview is active based on current URL supplied through `request` \n prop of `<CmsPage>`.\n\n#### Example\n\n```jsx\nimport React from 'react'\n\nconst content = this.props.content;\nconst manageContentButton = this.props.manageContentButton;\n\nclass Banner extends React.Component {\n  render() {\n    return (\n      <div className=\"my-content-component\">\n        { manageContentButton && manageContentButton }\n        { content.title && content.title }\n      </div>)\n  }\n}\n```\n\n### Static CMS components\n\nStatic CMS components are components that are defined by developers / administrators and cannot be  \nmodified by users in the CMS. However, any content or site menus these components reference can be \nchanged by users in the CMS.\n\nSince `<RenderCmsComponent>` only renders container components (drag-and-drop components) by default, \nyou have to specify two additional properties in order to render a static CMS component: the `path` \nproperty to point to the relative path of the component, and `renderComponent` to specify which React \ncomponent to use for rendering the component. See the example below.\n\n```jsx\n<RenderCmsComponent path={'menu'} renderComponent={CmsMenu} />\n```\n\n### More component examples\n\nFor more detailed examples, see the components included in the [example applications](https://github.com/bloomreach/experience-react-sdk/tree/master/examples/client-side-rendered/src/components). \n\n### Helper functions\n\nAdditionally, there are a variety of helper functions available. See the examples below. For full \ndetails on the APIs, see the API section.\n\n```jsx\nimport { createLink, getImageUrl, getNestedObject, parseAndRewriteLinks, parseDate } from 'bloomreach-experience-react-sdk'\n\nconst link = createLink('ref', link, linkText, className)\nconst image = getImageUrl(content.image, this.props.pageModel, this.props.preview)\nconst list = getNestedObject(configuration, ['models', 'pageable', 'items', 0])\nconst contentHtml = parseAndRewriteLinks(content.content.value, this.props.preview)\nconst date = parseDate(content.date)\n```\n\n## API\n\n### `<CmsPage>`\n\nThe CmsPage component is a higher-order component that takes care of:\n- Fetching the Page Model for client-side rendering, when not supplied as a prop.\n- Fetching Page Model updates on component changes in the CMS.\n- Initializing and managing state, and providing this as context to `<RenderCmsComponent>`.\n\n#### Properties\n\n- `cmsUrls` - `Object` Override default CMS URL's. (Optional)\n- `componentDefinitions` - `object` Mapping of CMS catalog components to React components. Determines \n what component to render based from the Page Model. (Optional)\n- `createLink` - `Function` Called when creating internal links so that links can be constructed using \n the router library of the React app. (Optional)\n- `pageModel` - `Object` Supply Page Model as prop. Used for server-side-rendering where Page Model API \n is fetched server-side. When supplied, `CmsPage` will not fetch Page Model API on mount, only on \n component updates in CMS. (Optional)\n- `request` - `String` Current URL-path for determining if preview mode is active, and for fetching the \n Page Model for the page that is active. (Required)\n\n###### `cmsUrls` property\n\nProperty that allows you to override the default URL's for fetching the Page Model API. Typically you \nwill only have to define `scheme`, `hostname`, `port`, and `contextPath`. Input object takes the \nfollowing properties (all are optional):\n- `scheme` - `String` scheme (default: *http*)\n- `hostname` - `String` hostname (default: *localhost*)\n- `port` - `number` port number (default: *8080*)\n- `contextPath` - `String` site context-path (default: *site*)\n- `channelPath` - `String` path to the used channel, if channel is accessed through a subpath\n- `previewPrefix` - `String` preview-prefix used by CMS (default: *_cmsinternal*)\n- `apiPath` - `String` path to Page Model API as subpath (default: *resourceapi*)\n- `apiComponentRenderingUrlSuffix` - `String` (default: *?_hn:type=component-rendering&_hn:ref=*)\n\n###### `componentDefinitions` property\n\nMaps CMS catalog components to React components. Expects as input an object with `hst:label` of the CMS \ncomponents as keys and as value another object. The nested object has the mandatory property `component` \nwho's value maps the CMS component to a React component. See the example below:\n\n```js\nconst componentDefinitions = {\n  \"MyCustomCmsComponent\": { component: MyCustomReactComponent },\n  \"AnotherCmsComponent\": { component: AnotherReactComponent, wrapInContentComponent: true }\n};\n```\n\nAdditionally, the property `wrapInContentComponent: true` can be used for components that reference a \nsingle content-item. When this property is set on a component, it will be wrapped in a convenient \nwrapper class. See section *Content components*.\n\n##### `createLink` property\n\nCalled when creating internal links so that links can be constructed using the router library of the \nReact app. \n\nTakes `Function` as input. The function should return valid JSX and have three parameters:\n- `href` - `String` href of link\n- `linkText` - `Function` contains the HTML that is wrapped inside the link. Is a function so that it \n can include HTML.\n- `className` - `String` classnames to add to the link element\n\nFor example:\n```jsx\nconst createLink = (href, linkText, className) => {\n  return (<Link className={className} to={href}>{linkText()}</Link>)\n}\n```\n\n##### `pageModel` property\n\nPage Model can be supplied as a prop when using a server-side rendered / isomorphic React framework. \nWhen supplied, `<CmsPage>` will not fetch the Page Model API client-side. \n\n##### `request` property\n\nTakes `Object` as input with properties `hostname` and `path`, both of type `String`. The property \n`hostname` should contain the hostname for the current request (client-side this is \nwindow.location.hostname). The property `path` should contain the URL-path for the current request \n(client-side this is window.location.pathname);\n\n### `<RenderCmsComponent>`\n\nRenders a CMS component and all of its children using the Page Model supplied by `<CmsPage>`. Will \nrender the entire Page Model by default.\n\n#### Properties\n\n- `path` - `String` path to a component (static CMS component), container or container-item in the Page \n Model to render only that component and its children. If no path is supplied, entire Page Model will be \n rendered. \n- `renderComponent` - `React.Component` render a static CMS component using specified React component. \n Only works in combination with `path` property, which should specify path to the static CMS component. \n Site menus that are rendered this way can leverage the `<CmsEditButton>` component for rendering edit \n buttons in the CMS.\n\n#### Example\n\n```jsx\n<RenderCmsComponent path={'menu'} renderComponent={CmsMenu} />\n```\n\n### `<CmsEditButton>`\n\nInserts meta-data for either a content-item or site menu for placing an edit button in preview mode in \nthe CMS. Content-items that are rendered by a content component using `wrapInContentComponent: true` do \nnot need to use this component, but should use the `manageContentButton` prop that passes the meta-data.\n\n#### Properties\n\n- `configuration` - `Object` configuration of the site menu (not the component configuration containing \nthe menu) or the content-item object which has the `_meta` object in its root.\n- `preview` - `Boolean` toggle to prevent edit buttons from being rendered outside of preview.\n\n### `getApiUrl(request, [newCmsUrls])`\n\nHelper function for generating URL to the Page Model API for server-side fetching of the Page Model. \n\n#### Arguments\n\n- `request` - `Object` containing hostname and URL-path as properties `hostname` and `path` \n respectively. See the `request` property section above.\n- `newCmsUrls` - `Object` takes `cmsUrls` property as input to override default CMS URL's\n\n#### Return types\n\n`String` returns URL for fetching Page Model API\n\n### `createLink(linkType, link, linkText, className)`\n\nCreates a link to either a component or content-item itself or a referenced content-item (can be a \ndocument, image or asset) and returns the link as JSX.  \n\n#### Arguments\n\n- `linkType` - `String` type of link to create. Valid values are `self`, `ref` or `href`.\n  - `self` - Create link to the component or content-item itself. E.g. for a news-item in a news \n   overview.\n  - `ref` - Create link to a referenced content-item. E.g. for a banner.\n  - `href` -  Used by `parseAndRewriteLinks()` to create links using a href only.\n- `link` - `Object` the component configuration or content-object that is linking to itself or \n referenced another content-item.\n- `linkText` - `JSX | Function` HTML to wrap inside the link. Is a function so that it can include HTML.\n- `className` - `String` classnames to add to the link element\n\n#### Return types\n\n`JSX` returns link as JSX object that can be included as a variable anywhere within the return section \nof a React component's render method.\n\n### `getImageUrl(imageRef, pageModel, preview)`\n\nCreates link to URL of image in case BloomReach Experience is used for serving images.\n\n#### Arguments\n\n- `imageRef` - `String` JSON Pointer that references the image.\n- `pageModel` - `Object` since this function is a pure JavaScript function it can't get Page Model from \n context, so it has to be provided as function parameter. The Page Model is used to retrieve the image.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by \n `<RenderCmsComponent>` can pass the prop `this.props.preview`.\n\n#### Return types\n\n`String` returns URL to image.\n\n### `getNestedObject(nestedObject, pathArray)`\n\nReturns a nested object or value using a path array. Useful when you need to access deeply nested \nobjects/values without having to string null checks together.\n\n#### Arguments\n\n- `nestedObject` - `Object` the object containing the nested object or value.\n- `pathArray` - `Array` contains the path to the nested object as an array.\n\n#### Return types\n\n`Object|null` returns the nested object if found, otherwise returns null. \n\n### `parseAndRewriteLinks(html, preview)`\n\nParses HTML of a rich-text field of a content-item for rewriting links in HTML to internal links. Uses \nthe `createLink` function passed to `<CmsPage>` for constructing internal links.\n\n#### Arguments\n\n- `html` - `String` value of rich-text field of a content-item. Should contain HTML only.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by \n `<RenderCmsComponent>` can pass the prop `this.props.preview`.\n\n#### Return types\n\n`JSX` returns parsed and rewrited HTML as JSX.\n\n### `parseDate(date)`\n\nParses date-field of a content item and returns date as a string.\n\n#### Arguments\n\n- `date` - `String` takes raw value of a date-field as input, following the ISO 8601:2000 format.\n\n#### Return types\n\n`String` returns date in full date format.\n\n## Release notes\n\n### Version 0.4.0\n\nAdded support for rendering static CMS components.\n- Added new property `renderComponent` to `<RenderCmsComponent>` which allows you to render a static \n component. This only works in combination with the `path` property, which should contain the relative \n path to the component.\n- Renamed `<ManageContentButton>` to `<CmsEditButton>` and exported it so it can be used by apps. This \n component is now more generic so it can also be used to generate edit buttons in the CMS for site menus.\n- Moved `<CmsMenu>` component out of SDK and into the example apps.\n\n\n### Version 0.3.0\n\nAdded extra checks so that `<div>` elements needed for CMS preview are only inserted in preview mode.\n\n### Version 0.2.0\n\nThis version includes significant changes. Please make sure to update your components using the upgrade \nsteps further down.\n- Changed `cmsUrls` property to support different live and preview URLs.\n- Changed `urlPath` property to `request` property which no longer takes URL-path as string, but an \n object with hostname and URL-path. This property should be passed to `<CmsPage>`.\n- Changed helper method `getApiUrl()` to take `request` property as parameter instead of `urlPath`.\n- Changed helper method `parseAndRewriteLinks()` to take an extra parameter: `preview`.\n- Changed helper method `getImageUrl()` to take an extra parameter: `preview`.\n\nUpgrade steps:\n- Modify `cmsUrls` property to include URLs for live and preview using the properties `live` and \n `preview` respectively. Please note that the `cms` prefix has been removed from all URL properties. So `cmsHostname` has become `hostname`. Preview URLs are optional. For example:\n  ```js\n  const cmsUrls = {\n    live: {\n      hostname: bloomreach.com\n    },\n    preview: {\n      hostname: cms.bloomreach.com\n    }\n  }\n  ```\n- Pass current request details through `request` property to `<CmsPage>`. This was previously done \n through the `urlPath` property. The `request` property should be an object that contains the hostname \n and path as properties `hostname` and `path` respectively. For example:\n  ```jsx\n  const request = { hostname: window.location.hostname, path: window.location.path };\n  <CmsPage componentDefinitions={componentDefinitions} request={request}>\n  ```\n- Update usage of `getApiUrl` to pass `request` property (see previous bullet) instead of URL-path.\n- Update usage of helper methods `getImageUrl()` and `parseAndRewriteLinks()` to include the preview \n parameter. Components rendered by `<RenderCmsComponent>` have the preview value passed as prop \n `this.props.preview`.\n\n## FAQ / Troubleshooting\n\nNothing here yet :)\n\n## Author\n\nRobbert Kauffman - BloomReach\n","gitHead":"9807b6658c17a2ffd1af78ad464e2a57236c2230","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"rkauffman","email":"robbertkauffman@gmail.com"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.4.1","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.11.0","dependencies":{"jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.4.5-rc1_1539201669408_0.8127068712010077","host":"s3://npm-registry-packages"}},"0.4.4":{"name":"bloomreach-experience-react-sdk","version":"0.4.4","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.4.4","maintainers":[{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"cb221a6a2ff66a9debb740e93f76a8e6ab6492d6","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.4.4.tgz","fileCount":28,"integrity":"sha512-fVSU/s7ZVjZzf1jH5KnFDGBBfoFqGa2CgEhl/rOfFiy8uRzcpOJXLCaLwPeL8rA64wLdBuZYOOKtmk2Veqzt5w==","signatures":[{"sig":"MEQCIH59bVQzBDA0RgFMbJvleG0IRvFIolmoWcP7x8LeN6PyAiB+/kelGkP+gSIz38pvAX5BnofiLW9UHm41F3qkkrAzcw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":242325,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb3J5tCRA9TVsSAnZWagAAtAoP/3ZTCdlLawj2rny6mgld\nGFOUXsLblB23KlaMcrRQqx1jSpMX0zIx1wOUkjWnkLbwhCnJVfLPPQ3Hs/D7\nG2AXOnzLKu4sQpotD9UF57In7ve5BpK70u8jlBXPlyTfYURM/WSDluSiXhWv\nHbEHEfHJZDstfcsr2LNBFHszMdUvNStXI46dYEjtSM4Ab0Vuo9a4a7wcrFAA\niqP5rzVtostcG/A8ECIJpGcSdpxaqmaGH7aPNQ/r4GJoyszwFCqs7niK9nj6\nlui0TAPfVdZa5LRaDq8z7LDheb8Cij1Wq/3zIt3bnIas1X12B9T5e3aShrAL\nSGJEU1QCLkD+QpZPwu02X6k101P02gP3oRT7dcOvl5lR8WysgvcPwZ6C5e+0\nZ9phsGbIe9BdlOIsNbxT86u5avlpSZeUi/4bsWUOe9LzIfg1jxW+WCUvEA+L\nRa/XDwOx3f9cQWcadAuyTHv0vLmP3qH2fuT4PIrmRy2WRo3FKe3FKZMo8yzO\nC8lHETLaUJuPItIxJzlxCPQRDy+i28ywEzw8zefnXOrmLFMXJYN5k9Fer+2D\nN8ols92VB01pW234VmVWS/5VcQFSvnSPXN5mlQmSn3Uu6rEtTlJpkA67+dQe\nQcUKI74Wd7yfekgI9Kj2lqns4f2BMJVpe26vfHmXS8RzYb+0vCkLy3IUsaUR\njPL7\r\n=UvAq\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","gitHead":"a66f58c37f9ea3ad4f168632cd1077ef5c9cfe6c","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"rkauffman","email":"robbertkauffman@gmail.com"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.4.1","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.11.0","dependencies":{"jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.4.4_1541185133017_0.2299338956522441","host":"s3://npm-registry-packages"}},"0.4.5-rc3":{"name":"bloomreach-experience-react-sdk","version":"0.4.5-rc3","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.4.5-rc3","maintainers":[{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"d945551e522c34a4b3898b0d0f464ca6cb1f1cf4","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.4.5-rc3.tgz","fileCount":27,"integrity":"sha512-pODAGE0UQF0WjjLLgeys+8YdhvXEjaB1IXK6o5tkyj3OvkAQZ+ZlSTHcbiT7zwnwWXxpjCyGnVJDhBOxKuWI4g==","signatures":[{"sig":"MEYCIQCSog6GxnGEpFxc2C8Z2AFHVvlCJ1A6BLUaYjmSYhX3MgIhAKU4WD1GKmMgZUBVieejpY9yBzRrGTTlGBxsrbZHWDDX","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":231241,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcCCBzCRA9TVsSAnZWagAAresP/RBcxEwM0k0bNxCxazTw\nrHFTg7px62wB6GGDgkYE8N3l0jIfG1dWx1WPafPNmKoQ5rsaNNE3hUHbUOVI\nNgbcK34fBe+BsiklQySi6FK9rh8LkOZHkOvwhboZEUFOgwWR/50iatRSDXOx\n8pLWgAzrQUcPCT32bJrcJ1d/YGyad5qLkEm9YvhXim4axqLziH/KjvtRqQCg\nJ7H5jtfVgQi3y55ZbX7TUghhE+Cdu7wm1wTMLOklG+/73oeYgL2a3ILEclQu\njSQdCGuMWGyC8cVD07fbm93/97Rky2gRodo3QJmwQJtZaRzlESebdvM1s4Ng\n34DkzPXbWZdsW1PLMgzBxuIKe4ORkFTQ/gfdSfKOSVM0Qvq5/p2UFiHrfAqu\n+j1ymqQzPupplFAxrnNfWQ0hTc0OPK32pxJZrHMnYK+b03idKzxQTqWWiTX7\nqrzoYKe9BVd/EJm6mVefIl3h8tlGRx2ROfJqbe0dVEelvKSmi9hwA3sP4FNv\nYLT9RCwPC7pOVV9A/Ni7BArGMbbneT8Fh5s2mh2/v/JiSlsTj0/QCZwvQiXg\nequ8r5JKBhdSOpX2r5+fxUB07g0neqMUCHs/By3NX5si4nnq0vdZ71L873Yn\nQxkM6OEqbjWun2JJ37VAItNovy1wMBOg3og2hF+phsNzHbA3KrutDOQYkUFh\nvy6z\r\n=YduW\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","gitHead":"156019abed6623d6c8c06ccffe567b3e94d5eadc","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"lachire","email":"charlie.chen@bloomreach.com"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"5.10.0","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"8.11.2","dependencies":{"axios":"^0.18.0","jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.4.5-rc3_1544036466163_0.260097188336617","host":"s3://npm-registry-packages"}},"0.4.5-rc4":{"name":"bloomreach-experience-react-sdk","version":"0.4.5-rc4","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.4.5-rc4","maintainers":[{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"fc42d5ae24706442a828f93ba94eb78c1f50d2fe","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.4.5-rc4.tgz","fileCount":27,"integrity":"sha512-W9H99xbijjwubkuQeGSSt6nVhoFFlWGljgXtM2mtdNF9MZCdqlaw0tzgehzJZoSCTpi4NaoXWHiClqc8pwCg2g==","signatures":[{"sig":"MEQCICG/+6YxvVCvtDMrAHeuoDFYM4Ej1vAI8x5DQFmmh67kAiAVVPArnnipVbw5iavORGbcyHt0tREJCJpiPHL/kaNUbQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":231241,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcCCcCCRA9TVsSAnZWagAAH+sP/1OPsjGhVqfzTq3256CD\ndXLOZJFW8ZfV+6tGnEh8lTXzVDovjHHzINc+jcKVssPgo283v/8DKG6GBUyW\nGwoVw8mKyA9UH23hdvWgQ9yGQqOOZ1UImwOwxrMXriTwImfxsOdjEuN+KNsR\nh8G8tEUfxE8ODYVNfd+vqJPlcargz2X3beCwnXK0ENz/9Pjzz1JYABDAeiou\n62/Ducv6juyVKeEJPPM0y4jjhhKMrHUhJAYK1HHxeHwjbKqckzQ/JpTUewQ6\ngENUIfKSYr8zsCxURWyaG4n3jCm5eg1niC0sTp+BdrY82fk7vY/CEcfelkDE\nXSqL3k47/qo8ONo4o2wMHnC9fJ8+3g2FoKUgyrOAgsgVshMdDaD134cLl2iY\n3op5T2lZcJCMxFut1wj0RHIGJGO6VVdy/F+29AQWoMVOthrvBCRBA2mi8M5N\n2TZmEI4Q3h7kKrLQgKs98XLFs354WWjMYki12YewQqNAe1shBk2rmQbRjVCC\n4tEcyIwl3Ri4GJ+1OHHHGCUJgkIp5k6dnlPf1K0YaK42YILizSQ9jZh/eaQd\nmdrx5hIcjPDkIvG+SLdOY00ZQ31uBr3vaAwZZZ/4YwLuUuSjayi4l9ANWyUL\nPnZqLxP3Gip5UoUt73TW4n8mZvh+Y1wZvVi6lt3M32ngZPLRtuSSZo+KENWq\nrh8Q\r\n=OXGh\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","readme":"# BloomReach Experience SDK for React\n\nSDK for powering content and components in React applications by [BloomReach Experience](https://www.bloomreach.com/en/products/experience). \nThis library makes integrating a React app with BloomReach Experience a breeze. It supports both \nclient-side- and server-side rendered/isomorphic React apps. \n\nBloomReach Experience allows you to use an external front-end such as React for rendering while still \nproviding a native-like authoring experience, such as integrated preview, in-context editing, drag & \ndrop, server-side personalization. For more information on this approach, see [A new approach to \nintegrating SPA's with WCM: Fixing what's wrong with headless integrations](https://www.bloomreach.com/en/blog/2018/03/a-new-approach-to-integrating-spas-with-wcm-fixing-what%E2%80%99s-wrong-with-headless-integrations.html).\n\n## Install\n\n```bash\nnpm install --save bloomreach-experience-react-sdk\n```\n\n## Usage\n\n```jsx\nimport React from 'react'\nimport { CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\nconst componentDefinitions = {\n  \"MyCustomComponent\": { component: MyCustomComponent }\n}\n\nclass MyApp extends React.Component {\n  render() {\n    const request = { hostname: window.location.hostname, path: window.location.pathname };\n    return (\n      <CmsPage componentDefinitions={componentDefinitions} request={request}>\n        { () =>\n          <RenderCmsComponent />\n        }\n      </CmsPage>\n    )\n  }\n}\n```\n\nAt a minimum, `<CmsPage>` and `<RenderCmsComponent>` should be imported in the React app.\n\n`<CmsPage>` fetches the Page Model when it is not supplied as a prop (see section on server-side \nrendering); it fetches updates to the page model on component changes in the CMS; and it initializes and \nmanages state, and provides this as context to `<RenderCmsComponent>`. The `<CmsPage>` component can be \nput anywhere within the React App.\n\n`<RenderCmsComponent>` renders components based on the Page Model API response. It consumes the state \nfrom `<CmsPage>` and renders the container components and any content referenced from the components as \ncontained in the Page Model API response. The `<RenderCmsComponent>` should be nested within `<CmsPage>` \nand placed in the React app at the exact location where you want BloomReach Experience to control what \ncomponents and content is rendered.\n\nPlease note that `<CmsPage>` takes children as a function instead of as a prop, because it is not \npossible to provide state through context providers due to a bug in React currently. So make sure to \nwrap any children of `<CmsPage>` in a function, as in the following example:\n\n ```jsx\n{ () =>\n  // any children go here\n  <h1>Blooming is what I do</h1>\n}\n ```\n\n`<CmsPage>` takes two props: `componentDefinitions` and `request`.\n\nThe `request` prop is used to fetch the Page Model for the current page; and to detect whether \npreview mode is active so that meta-data for Channel Manager functionality (e.g. in-context editing) is \nincluded in the HTML, and consequently Channel Manager functionality is enabled.\n\nFinally, component definitions are supplied through the `componentDefinitions` prop. The component \ndefinitions tell `<RenderCmsComponent>` what React component to render by mapping these to the \n*hst:label* of a CMS catalog component.\n\n## Server-side rendering\n\nFor server-side rendering (e.g. using [Next.js](https://github.com/zeit/next.js)) you need to fetch the \nPage Model API server-side and supply it as a prop to `<CmsPage>`. Apart from this the usage is the same \nas with client-side rendering.\n\nThe helper function `getApiUrl()` can be used to generate the Page Model API URL using the current \nrequest.\n\nIt is important to pass cookies from the initial request and supply these with the request header of the \nPage Model API request. Otherwise you will get a 403 error in preview mode.\n\nFinally, to get preview to work for server-side rendered apps you can use a reverse proxy to route \nrequests from BloomReach's site preview to the React App-server. For more details, see section *3.2 \nServer-side apps* of the Hippo Lab: [Integrate a React application with BloomReach Experience](https://www.onehippo.org/labs/integrate-a-react-application-with-bloomreach-experience.html).\n\n```jsx\nimport fetch from 'isomorphic-unfetch'\nimport { getApiUrl, CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\n// setting pageModel to empty list instead of null value,\n// as otherwise the API will be fetched client-side again after server-side fetch errors\nlet pageModel = {}\n\nconst request = { hostname: req.headers.host, path: asPath }\nconst url = getApiUrl(request, {})\n// pass cookies of initial request for CMS preview\nconst response = await fetch(url, {headers: {'Cookie': req.headers.cookie}})\n\nif (response.ok) {\n  try {\n    pageModel = await response.json()\n  } catch (err) {\n    console.log(`Error! Could not convert response to JSON for URL: ${url}`)\n  }\n} else {\n  console.log(`Error! Status code ${response.status} while fetching CMS page data for URL: ${url}`)\n}\n```  \n\n## Example React apps\n\nThere are two example React apps available that use the SDK. One client-side rendered, and one \nserver-side rendered using [Next.js](https://github.com/zeit/next.js). You can find the [example apps on \nGithub](https://github.com/bloomreach/experience-react-sdk/tree/master/examples).\n\n## Creating custom components\n\nAny components that are supplied through the `compenentDefinitions` prop can be any type of valid React \ncomponent, including functional components. Props are passed to these components as context so that you \ncan access the components' configuration, content, etc. See more information below.\n\n### Props\n\nThe following props are passed to a component that is rendered by `<RenderCmsComponent>`:\n- `configuration` - `Object` component configuration. Contains the contributed models, raw parameters \n and resolved parameters. Content included in the component's model is not serialized as part of the \n component's configuration but in a separate content object, and a JSON Pointer reference is used to \n link to the actual content object. This is done to prevent content from being included multiple times \n in the API response when referenced multiple times on a page. \n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview mode is active based on current URL supplied through \n `request` prop of `<CmsPage>`.\n\nFor more information on the Page Model API response, see the [Swagger documentation](https://www.onehippo.org/library/concepts/spa-plus/page-model-api/swagger-api-documentation.html).\n\n### Example\n\n```jsx\nimport React from 'react'\nimport NewsItem from './news-item'\nimport { getNestedObject } from 'bloomreach-experience-react-sdk'\n\nexport default class NewsList extends React.Component {\n  render() {\n    const preview = this.props.preview\n    const pageModel = this.props.pageModel\n    const configuration = this.props.configuration\n\n    // return placeholder if no list is set on component\n    const list = getNestedObject(configuration, ['models', 'pageable', 'items'])\n    if (!list && preview) {\n      return (<p>Click to configure {configuration.label}</p>)\n    } else if (!list) {\n      // don't render placeholder outside of preview mode\n      return null\n    }\n\n    // build list of news articles\n    const listItems = list.map((listItem, index) => {\n      if ('$ref' in listItem) {\n        return (<NewsItem contentRef={listItem.$ref} pageModel={pageModel} preview={preview} key={index}/>)\n      }\n    })\n\n    return (\n      <div className=\"row\">\n        <div className=\"col-sm-12 news-list\">\n          {listItems}\n        </div>\n      </div>\n    )\n  }\n}\n```\n\n### Content components\n\nComponents that reference a single content-item (e.g. the Banner component) can use a convenient \nwrapper-class that looks up the content and passes it as a prop. See below.\n\nTo enable this, the property `wrapInContentComponent: true` has to be set on the component in the \n`componentDefinitions` prop. See `componentDefinitions` in the API section for more details.\n\n#### Props\n\n- `content` - `Object` raw content object that contains the content-item's fields and field-values. Any \n references to other content-items (e.g. images) are serialized as JSON Pointers.\n- `manageContentButton` - `React.Component` for placement and rendering of the [Manage Content Button](https://www.onehippo.org/library/concepts/component-development/render-manage-content-button.html)\n in preview mode in CMS.\n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview is active based on current URL supplied through `request` \n prop of `<CmsPage>`.\n\n#### Example\n\n```jsx\nimport React from 'react'\n\nconst content = this.props.content;\nconst manageContentButton = this.props.manageContentButton;\n\nclass Banner extends React.Component {\n  render() {\n    return (\n      <div className=\"my-content-component\">\n        { manageContentButton && manageContentButton }\n        { content.title && content.title }\n      </div>)\n  }\n}\n```\n\n### Static CMS components\n\nStatic CMS components are components that are defined by developers / administrators and cannot be  \nmodified by users in the CMS. However, any content or site menus these components reference can be \nchanged by users in the CMS.\n\nSince `<RenderCmsComponent>` only renders container components (drag-and-drop components) by default, \nyou have to specify two additional properties in order to render a static CMS component: the `path` \nproperty to point to the relative path of the component, and `renderComponent` to specify which React \ncomponent to use for rendering the component. See the example below.\n\n```jsx\n<RenderCmsComponent path={'menu'} renderComponent={CmsMenu} />\n```\n\n### More component examples\n\nFor more detailed examples, see the components included in the [example applications](https://github.com/bloomreach/experience-react-sdk/tree/master/examples/client-side-rendered/src/components). \n\n### Helper functions\n\nAdditionally, there are a variety of helper functions available. See the examples below. For full \ndetails on the APIs, see the API section.\n\n```jsx\nimport { createLink, getImageUrl, getNestedObject, parseAndRewriteLinks, parseDate } from 'bloomreach-experience-react-sdk'\n\nconst link = createLink('ref', link, linkText, className)\nconst image = getImageUrl(content.image, this.props.pageModel, this.props.preview)\nconst list = getNestedObject(configuration, ['models', 'pageable', 'items', 0])\nconst contentHtml = parseAndRewriteLinks(content.content.value, this.props.preview)\nconst date = parseDate(content.date)\n```\n\n## API\n\n### `<CmsPage>`\n\nThe CmsPage component is a higher-order component that takes care of:\n- Fetching the Page Model for client-side rendering, when not supplied as a prop.\n- Fetching Page Model updates on component changes in the CMS.\n- Initializing and managing state, and providing this as context to `<RenderCmsComponent>`.\n\n#### Properties\n\n- `cmsUrls` - `Object` Override default CMS URL's. (Optional)\n- `componentDefinitions` - `object` Mapping of CMS catalog components to React components. Determines \n what component to render based from the Page Model. (Optional)\n- `createLink` - `Function` Called when creating internal links so that links can be constructed using \n the router library of the React app. (Optional)\n- `pageModel` - `Object` Supply Page Model as prop. Used for server-side-rendering where Page Model API \n is fetched server-side. When supplied, `CmsPage` will not fetch Page Model API on mount, only on \n component updates in CMS. (Optional)\n- `request` - `String` Current URL-path for determining if preview mode is active, and for fetching the \n Page Model for the page that is active. (Required)\n\n###### `cmsUrls` property\n\nProperty that allows you to override the default URL's for fetching the Page Model API. Typically you \nwill only have to define `scheme`, `hostname`, `port`, and `contextPath`. Input object takes the \nfollowing properties (all are optional):\n- `scheme` - `String` scheme (default: *http*)\n- `hostname` - `String` hostname (default: *localhost*)\n- `port` - `number` port number (default: *8080*)\n- `contextPath` - `String` site context-path (default: *site*)\n- `channelPath` - `String` path to the used channel, if channel is accessed through a subpath\n- `previewPrefix` - `String` preview-prefix used by CMS (default: *_cmsinternal*)\n- `apiPath` - `String` path to Page Model API as subpath (default: *resourceapi*)\n- `apiComponentRenderingUrlSuffix` - `String` (default: *?_hn:type=component-rendering&_hn:ref=*)\n\n###### `componentDefinitions` property\n\nMaps CMS catalog components to React components. Expects as input an object with `hst:label` of the CMS \ncomponents as keys and as value another object. The nested object has the mandatory property `component` \nwho's value maps the CMS component to a React component. See the example below:\n\n```js\nconst componentDefinitions = {\n  \"MyCustomCmsComponent\": { component: MyCustomReactComponent },\n  \"AnotherCmsComponent\": { component: AnotherReactComponent, wrapInContentComponent: true }\n};\n```\n\nAdditionally, the property `wrapInContentComponent: true` can be used for components that reference a \nsingle content-item. When this property is set on a component, it will be wrapped in a convenient \nwrapper class. See section *Content components*.\n\n##### `createLink` property\n\nCalled when creating internal links so that links can be constructed using the router library of the \nReact app. \n\nTakes `Function` as input. The function should return valid JSX and have three parameters:\n- `href` - `String` href of link\n- `linkText` - `Function` contains the HTML that is wrapped inside the link. Is a function so that it \n can include HTML.\n- `className` - `String` classnames to add to the link element\n\nFor example:\n```jsx\nconst createLink = (href, linkText, className) => {\n  return (<Link className={className} to={href}>{linkText()}</Link>)\n}\n```\n\n##### `pageModel` property\n\nPage Model can be supplied as a prop when using a server-side rendered / isomorphic React framework. \nWhen supplied, `<CmsPage>` will not fetch the Page Model API client-side. \n\n##### `request` property\n\nTakes `Object` as input with properties `hostname` and `path`, both of type `String`. The property \n`hostname` should contain the hostname for the current request (client-side this is \nwindow.location.hostname). The property `path` should contain the URL-path for the current request \n(client-side this is window.location.pathname);\n\n### `<RenderCmsComponent>`\n\nRenders a CMS component and all of its children using the Page Model supplied by `<CmsPage>`. Will \nrender the entire Page Model by default.\n\n#### Properties\n\n- `path` - `String` path to a component (static CMS component), container or container-item in the Page \n Model to render only that component and its children. If no path is supplied, entire Page Model will be \n rendered. \n- `renderComponent` - `React.Component` render a static CMS component using specified React component. \n Only works in combination with `path` property, which should specify path to the static CMS component. \n Site menus that are rendered this way can leverage the `<CmsEditButton>` component for rendering edit \n buttons in the CMS.\n\n#### Example\n\n```jsx\n<RenderCmsComponent path={'menu'} renderComponent={CmsMenu} />\n```\n\n### `<CmsEditButton>`\n\nInserts meta-data for either a content-item or site menu for placing an edit button in preview mode in \nthe CMS. Content-items that are rendered by a content component using `wrapInContentComponent: true` do \nnot need to use this component, but should use the `manageContentButton` prop that passes the meta-data.\n\n#### Properties\n\n- `configuration` - `Object` configuration of the site menu (not the component configuration containing \nthe menu) or the content-item object which has the `_meta` object in its root.\n- `preview` - `Boolean` toggle to prevent edit buttons from being rendered outside of preview.\n\n### `getApiUrl(request, [newCmsUrls])`\n\nHelper function for generating URL to the Page Model API for server-side fetching of the Page Model. \n\n#### Arguments\n\n- `request` - `Object` containing hostname and URL-path as properties `hostname` and `path` \n respectively. See the `request` property section above.\n- `newCmsUrls` - `Object` takes `cmsUrls` property as input to override default CMS URL's\n\n#### Return types\n\n`String` returns URL for fetching Page Model API\n\n### `createLink(linkType, link, linkText, className)`\n\nCreates a link to either a component or content-item itself or a referenced content-item (can be a \ndocument, image or asset) and returns the link as JSX.  \n\n#### Arguments\n\n- `linkType` - `String` type of link to create. Valid values are `self`, `ref` or `href`.\n  - `self` - Create link to the component or content-item itself. E.g. for a news-item in a news \n   overview.\n  - `ref` - Create link to a referenced content-item. E.g. for a banner.\n  - `href` -  Used by `parseAndRewriteLinks()` to create links using a href only.\n- `link` - `Object` the component configuration or content-object that is linking to itself or \n referenced another content-item.\n- `linkText` - `JSX | Function` HTML to wrap inside the link. Is a function so that it can include HTML.\n- `className` - `String` classnames to add to the link element\n\n#### Return types\n\n`JSX` returns link as JSX object that can be included as a variable anywhere within the return section \nof a React component's render method.\n\n### `getImageUrl(imageRef, pageModel, preview)`\n\nCreates link to URL of image in case BloomReach Experience is used for serving images.\n\n#### Arguments\n\n- `imageRef` - `String` JSON Pointer that references the image.\n- `pageModel` - `Object` since this function is a pure JavaScript function it can't get Page Model from \n context, so it has to be provided as function parameter. The Page Model is used to retrieve the image.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by \n `<RenderCmsComponent>` can pass the prop `this.props.preview`.\n\n#### Return types\n\n`String` returns URL to image.\n\n### `getNestedObject(nestedObject, pathArray)`\n\nReturns a nested object or value using a path array. Useful when you need to access deeply nested \nobjects/values without having to string null checks together.\n\n#### Arguments\n\n- `nestedObject` - `Object` the object containing the nested object or value.\n- `pathArray` - `Array` contains the path to the nested object as an array.\n\n#### Return types\n\n`Object|null` returns the nested object if found, otherwise returns null. \n\n### `parseAndRewriteLinks(html, preview)`\n\nParses HTML of a rich-text field of a content-item for rewriting links in HTML to internal links. Uses \nthe `createLink` function passed to `<CmsPage>` for constructing internal links.\n\n#### Arguments\n\n- `html` - `String` value of rich-text field of a content-item. Should contain HTML only.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by \n `<RenderCmsComponent>` can pass the prop `this.props.preview`.\n\n#### Return types\n\n`JSX` returns parsed and rewrited HTML as JSX.\n\n### `parseDate(date)`\n\nParses date-field of a content item and returns date as a string.\n\n#### Arguments\n\n- `date` - `String` takes raw value of a date-field as input, following the ISO 8601:2000 format.\n\n#### Return types\n\n`String` returns date in full date format.\n\n## Release notes\n\n### Version 0.4.0\n\nAdded support for rendering static CMS components.\n- Added new property `renderComponent` to `<RenderCmsComponent>` which allows you to render a static \n component. This only works in combination with the `path` property, which should contain the relative \n path to the component.\n- Renamed `<ManageContentButton>` to `<CmsEditButton>` and exported it so it can be used by apps. This \n component is now more generic so it can also be used to generate edit buttons in the CMS for site menus.\n- Moved `<CmsMenu>` component out of SDK and into the example apps.\n\n\n### Version 0.3.0\n\nAdded extra checks so that `<div>` elements needed for CMS preview are only inserted in preview mode.\n\n### Version 0.2.0\n\nThis version includes significant changes. Please make sure to update your components using the upgrade \nsteps further down.\n- Changed `cmsUrls` property to support different live and preview URLs.\n- Changed `urlPath` property to `request` property which no longer takes URL-path as string, but an \n object with hostname and URL-path. This property should be passed to `<CmsPage>`.\n- Changed helper method `getApiUrl()` to take `request` property as parameter instead of `urlPath`.\n- Changed helper method `parseAndRewriteLinks()` to take an extra parameter: `preview`.\n- Changed helper method `getImageUrl()` to take an extra parameter: `preview`.\n\nUpgrade steps:\n- Modify `cmsUrls` property to include URLs for live and preview using the properties `live` and \n `preview` respectively. Please note that the `cms` prefix has been removed from all URL properties. So `cmsHostname` has become `hostname`. Preview URLs are optional. For example:\n  ```js\n  const cmsUrls = {\n    live: {\n      hostname: bloomreach.com\n    },\n    preview: {\n      hostname: cms.bloomreach.com\n    }\n  }\n  ```\n- Pass current request details through `request` property to `<CmsPage>`. This was previously done \n through the `urlPath` property. The `request` property should be an object that contains the hostname \n and path as properties `hostname` and `path` respectively. For example:\n  ```jsx\n  const request = { hostname: window.location.hostname, path: window.location.path };\n  <CmsPage componentDefinitions={componentDefinitions} request={request}>\n  ```\n- Update usage of `getApiUrl` to pass `request` property (see previous bullet) instead of URL-path.\n- Update usage of helper methods `getImageUrl()` and `parseAndRewriteLinks()` to include the preview \n parameter. Components rendered by `<RenderCmsComponent>` have the preview value passed as prop \n `this.props.preview`.\n\n## FAQ / Troubleshooting\n\nNothing here yet :)\n\n## Author\n\nRobbert Kauffman - BloomReach\n","gitHead":"156019abed6623d6c8c06ccffe567b3e94d5eadc","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"lachire","email":"charlie.chen@bloomreach.com"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"5.10.0","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"8.11.2","dependencies":{"axios":"^0.18.0","jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.4.5-rc4_1544038145645_0.7067512972540775","host":"s3://npm-registry-packages"}},"0.4.5-rc5":{"name":"bloomreach-experience-react-sdk","version":"0.4.5-rc5","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.4.5-rc5","maintainers":[{"name":"abogaart","email":"arthur.bogaart@bloomreach.com"},{"name":"br-mikedreynolds","email":"mike.reynolds@bloomreach.com"},{"name":"dokmic","email":"m@dokol.in"},{"name":"joerideg","email":"joerideg@gmail.com"},{"name":"kenansalic","email":"kenan.salic@gmail.com"},{"name":"lachire","email":"charlie.chen@bloomreach.com"},{"name":"mdenburger","email":"mdenburger@gmail.com"},{"name":"namendes","email":"namendes@gmail.com"},{"name":"pcentgraf-bloomreach","email":"peter.centgraf@bloomreach.com"},{"name":"rkauffman","email":"robbertkauffman@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"9f48627cb62de6e5dfc68eadb47f94e60826b89d","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.4.5-rc5.tgz","fileCount":27,"integrity":"sha512-Z6WwSoMAV3FFfBILEkdRXAN/p8+dcVqkRv3/3OtZJG0rs5WCbHf4ICFh8gFhnBgZNb7rQoAI7MeZxHR8kAvqGg==","signatures":[{"sig":"MEYCIQDhZAbpyPkESSkPBhRLl0yebJvkJuGdmGUkgSIPgOZ1dwIhAPsI4yuBouFo1GcZY1PZzS1aN03taIuKnyhdU1w5tpdW","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":233448,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcUbxhCRA9TVsSAnZWagAAS8QP/34QKNchPjkd6l0ADhGP\nvs988M0xUlbtJgfZc73yhflcDOhyaC6HX4amm3k7yicYunM6S4lrO1ralErU\nfiC8KRgoQyF7WR4pedIUlsm76yCPo2rebDjTb8/9l9lHeq7B6+Q2G9XD8HLF\n8A3q5oLyPt8eXupS2ybcMO5H40PIxgbLu0EM1td3/3F4KJJ25kmxYLJgWFne\nJY0Sm7gZEZGy+E0KgbD+42bZnqKb0Yrta5MJCOOwyKNcWmhkW/T+KpwIaGHR\nrtuRU1ptGNJ0a2OVL8qH0wlMbOj+2oWr81ypYc8BccaGwfgRNVPudoLs76l6\nE4zJ+LJObV2Cur2MnjffBeR6dtf99XeqMKQIO+SUIoRIx9lffy11TyFbg557\n9r/S0Tp3J9MOYJyDs4LloOZUOIIYp0ITZqy13qYhfBzCeil6rRZjy9lxp0cN\n5K00YuET6/wYcnUeWE7AMdBzoTaMYH81A79H6VyuXnj0OTf2qQVxCXAXXHhf\nVZeujlLnN48zllY0rgvsAYR0BDunmC/o01B0jI/EowbJ+2uoFXBj7EtgvMyq\nyTWOY54N6XbMp+jNoc0+YvGWms9y2UGgSmwU+lTkZKhbPIepqN1PKvtynopE\nJOWKea8ERggqoFv8rf2JkzmFItwdBy8nnXK9SlLbatHYYM0/z7pAJhsUcWFk\nqsOq\r\n=Blyg\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","gitHead":"783f5b1d861be4d62b01cb6d80f21c25ee556382","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"dokmic","email":"m@dokol.in"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.4.1","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.10.0","dependencies":{"axios":"^0.18.0","jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.4.5-rc5_1548860512534_0.5262852813245726","host":"s3://npm-registry-packages"}},"0.5.0-rc1":{"name":"bloomreach-experience-react-sdk","version":"0.5.0-rc1","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.5.0-rc1","maintainers":[{"name":"abogaart","email":"arthur.bogaart@bloomreach.com"},{"name":"ajbanck","email":"arent-jan.banck@bloomreach.com"},{"name":"br-mikedreynolds","email":"mike.reynolds@bloomreach.com"},{"name":"dokmic","email":"m@dokol.in"},{"name":"joerideg","email":"joerideg@gmail.com"},{"name":"kenansalic","email":"kenan.salic@gmail.com"},{"name":"lachire","email":"charlie.chen@bloomreach.com"},{"name":"mdenburger","email":"mdenburger@gmail.com"},{"name":"michielrop","email":"michiel.rop@bloomreach.com"},{"name":"mjmetter","email":"michael.metternich@bloomreach.com"},{"name":"namendes","email":"namendes@gmail.com"},{"name":"pcentgraf-bloomreach","email":"peter.centgraf@bloomreach.com"},{"name":"sshepelevich","email":"sergey.shepelevich@bloomreach.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"262178769d23d6f8b969a815f5f4982cce9639ad","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.5.0-rc1.tgz","fileCount":27,"integrity":"sha512-g+ZIBzfOZMn8CrN82D+UFNkpzqGokEJg4NmN7Jnb9cwY49p8gWFu3/vfXmQuNXIGqBhC+mpnobPdPMuzuk1sVA==","signatures":[{"sig":"MEUCIQDO7CTd2zC3WUkQAsfCVDGfSxIq+L/LkVMl/akcGHKN2AIgVbMUUPZFd3xU+WYoaIh/O2gtXkv5QpM0sH8vMlF8/6s=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":235168,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJc5rB3CRA9TVsSAnZWagAA5f8P/RNt1KMyiuofxwYaRjwP\nzypkefyFyQrR7zlir1Cf11J9WLeJDI756M8g3Vj5C8q8YKRy7B4xY14fpBKa\nXq3a74ApCtKBWD+8ORaQdJTu2QdWBjCXA0qUDKtQQ/Ro9eKIe8AnDYYBewFC\n1HrrgyaViD0mwWaFBbiRL0skWQnkBalCKytv2XlprnQ+7eHoktHxusS8G+wT\ntXeNZAwPJ2W48hj/4yLGdKD7Qy0f1vK2BsfDSvv7FCELFVzZilY5qEph6+uN\nCRUHm5inS/IsgQ5waF6LTJfTuBw7y9YEo+X9OJ8u7qSQvgAUpN5Xrz4prcYq\nxb1rDmtDJ7WrwdvuF+IBu+8/viITjB18Tjpzt7QhGeG8thYmIQUety+6m6tZ\ntEKbqJ365QSuwjc8lNZ37wb7f/K0L+8Tjns7EDJD4BHs7/PrJNppwQG44JiB\n5QLfYaJ1Av+HqWtjGNJCYHiUF7pXKsAt7ticscBuoP2DiCZA1KY9FaMw/88C\ne1G1EIYO9zE+pMuJkMdmXVSZY3GBhfhvQa42jk8g10Kk087OrOKZ3bruG1u1\n5FZ+TBfkMbHgzkaFngVY0bhMtHniAA5x1UtNh+WAonu4/krNcU46Fe5trDSA\nWHsajEbtW0Veaf5pYHDi//SHKQxD05OnXHT4zBpnKKQh7ZTCX0OQBBRaRxEf\nb9O2\r\n=skoI\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","gitHead":"8bcb3c6bdd4e2f0efb0cfc6e26c675688d8aa648","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"dokmic","email":"m@dokol.in"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.4.1","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.10.0","dependencies":{"axios":"^0.18.0","jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.5.0-rc1_1558622326529_0.11276302899298352","host":"s3://npm-registry-packages"}},"0.5.1":{"name":"bloomreach-experience-react-sdk","version":"0.5.1","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.5.1","maintainers":[{"name":"abogaart","email":"arthur.bogaart@bloomreach.com"},{"name":"ajbanck","email":"arent-jan.banck@bloomreach.com"},{"name":"br-mikedreynolds","email":"mike.reynolds@bloomreach.com"},{"name":"dokmic","email":"m@dokol.in"},{"name":"joerideg","email":"joerideg@gmail.com"},{"name":"jtsengyc","email":"jtsengyc@gmail.com"},{"name":"kenansalic","email":"kenan.salic@gmail.com"},{"name":"lachire","email":"charlie.chen@bloomreach.com"},{"name":"mdenburger","email":"mdenburger@gmail.com"},{"name":"michiel_eggermont","email":"michiel.eggermont@bloomreach.com"},{"name":"michielrop","email":"michiel.rop@bloomreach.com"},{"name":"mjmetter","email":"michael.metternich@bloomreach.com"},{"name":"mpalenov","email":"maxim.palenov@bloomreach.com"},{"name":"namendes","email":"namendes@gmail.com"},{"name":"pcentgraf-bloomreach","email":"peter.centgraf@bloomreach.com"},{"name":"sshepelevich","email":"sergey.shepelevich@bloomreach.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"c95b5f859fa316d548acfeb99b0cc98cbf665bc5","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.5.1.tgz","fileCount":27,"integrity":"sha512-Ih9Wkfy4Nx8qm1+Zawb959BMHAsItoVE3G8h6G7uWAZcOmi56DyN82rfiXcJZpkIbT/400LuIP/HJP1mDd4txg==","signatures":[{"sig":"MEQCIFleBB/R9VHh3RKSGcDLJ70UR9Y5w5fRqKNsbKu+n5nNAiA4YxBeXZmkGk7SCdhBv9OaUjsS+G2kj6AP6L+TDCTx+A==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":233791,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdRDK1CRA9TVsSAnZWagAAVGsP/AxlF5sGRSEg6heienpX\n7CwW2YxKjboklb6cD7SggB0guBC9cSowxupwvehRB9jIpvmSDIgGwQI+imqI\nkBNuH/a4WvH2U9GMe7tq8luBq6mLo7APJaS7herPqbXio4j9uTlkR+NfxYMO\nBjg4iQZAkbh2l+qjrMdLsdlXpDBz0tXCzl6EjKYojH0ZuO+Tqrj+JD2zUuW9\nGtYvG6TlTEXqzrNhRRgkxmRAjHcDAkTPd9Qcx84BBpbWEQMRppWy01Mbm829\nyjfDnDe2Zjnr5Gh5s+K0LM1AhdJvmrd9joHzhL76w04ainpeqdfYXfRu8hYf\noZlgP3h+N108XmSNcnZ9NPuBoMGFG73RVSyqb+MwvJtC1jnt8sLjGFcd/pHD\nlMEBwNHc0jMZYJwhgEPFJ5ZJnA5iGpEMqsiKpGLF1nQymRsl+60ZwAzA5LkU\nY0BYraRL5v3CAqIxQsUNdOf9mp0KeD4rSzMyDglpiL/YrHd1qpjwQ0d8wLui\nFRUCsra1s5jR7+4oPl8N92bxKrGaEk6kLW4c1hjZU20W7F+BccsMf09Xaidv\n/fFE8uGI3ZqTqRr5ROonNzaFtvNN4VA7XPf4091ww8iqG2udWDeHnB7nz4+I\n99ow+rkpb63Uv2UZDOqKCnhqvlf9U1D0BDAMiKAYjRgtStvWfGFLrzXhcNHs\noeFf\r\n=dDzT\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","gitHead":"214f1e3d782d50a9164872be5e26d970a1a19dc2","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"dokmic","email":"m@dokol.in"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.4.1","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.10.0","dependencies":{"axios":"^0.18.0","jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.5.1_1564750516064_0.23254149135697832","host":"s3://npm-registry-packages"}},"0.5.2":{"name":"bloomreach-experience-react-sdk","version":"0.5.2","keywords":["react","bloomreach"],"author":{"name":"Robbert Kauffman"},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.5.2","maintainers":[{"name":"abogaart","email":"arthur.bogaart@bloomreach.com"},{"name":"ajbanck","email":"arent-jan.banck@bloomreach.com"},{"name":"br-mikedreynolds","email":"mike.reynolds@bloomreach.com"},{"name":"dokmic","email":"m@dokol.in"},{"name":"joerideg","email":"joerideg@gmail.com"},{"name":"jtsengyc","email":"jtsengyc@gmail.com"},{"name":"kenansalic","email":"kenan.salic@gmail.com"},{"name":"lachire","email":"charlie.chen@bloomreach.com"},{"name":"mdenburger","email":"mdenburger@gmail.com"},{"name":"michiel_eggermont","email":"michiel.eggermont@bloomreach.com"},{"name":"michielrop","email":"michiel.rop@bloomreach.com"},{"name":"mjmetter","email":"michael.metternich@bloomreach.com"},{"name":"mpalenov","email":"maxim.palenov@bloomreach.com"},{"name":"namendes","email":"namendes@gmail.com"},{"name":"pcentgraf-bloomreach","email":"peter.centgraf@bloomreach.com"},{"name":"sshepelevich","email":"sergey.shepelevich@bloomreach.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://github.com/bloomreach/experience-react-sdk/issues"},"dist":{"shasum":"ea670a62e874b989d70ac06cf02fc80fec5e87ae","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.5.2.tgz","fileCount":27,"integrity":"sha512-TJ3EzZNePPy/bNr5VhH9aDHGNdK5NSuZ51WqyzpAOP0uQJvYKeIBRLgiBF0jAbelB/SOVUdbFmties1LEaD9Cw==","signatures":[{"sig":"MEQCIAXV9e5OHmnEehx6TsFO6l+JQ18clfMTA6fdh5synl6NAiANRFejO8ZawdtvM+mDq/44sWWUhOilSA5Udojk9aRCmQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":273086,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdUpwTCRA9TVsSAnZWagAAiz4P/2aJdaZKgXNhGtA2tUHV\nK6cr5SvBWL32ZuNS7a3ZOerzELn/0etru0C1i1F2N2FIR3Fo0HF/u1j7S6ng\nEvLtoEelY6ZxG/iNgiyaNyTpKFAQGDnkW04zZP7NKXU+LK5XVMDIx5PnidsR\nlCBn9pqm4iZ6i5nW+2fRWQLGaXx5iRetjl75cu4yO3xF5RLULRipaxmXvRtE\nvHUWBFO5JHd8hrgWRfUFl+aoMDVEE/FzmN2sh/kkAxV4oNvaUUL9z6xm2Ptg\n310WWx/dF9p8LgRDrIqX9rog0QivVQb12ZPFyqViQCf/R/Cq4CCGe2hnX6YE\nZq22tPB32CBc8xiC8Gp1jkNNh0f0iM1OuDBVfhmrNzPcXfifYlvu8AESAi8/\neqIm5vC6CcTXr1tkpOQclM9h8N6bka5RKMY934na8a6pLF3GHFKxfx0X8BNl\n55yhHtTMtiZlRQ4s/GqyIB+XRpSeXo7mDhedc7izEFkn8cF20nHk31umhvWp\n/Gt4UFB5xxalrPSuOOEcE8Mz9ch8j26eJsKfniVHY1ZaTFJ+Vpvja2y0Sovq\nirFmZB/6Ryl0h9rz7LK1Th1JXwsV5ByaM3fTAGR4/91Hha2QJ0mh6BTWAaCj\n8mNVUNczutXFa7xgDq53aVJ5autNULtgQv0yulaDTgKE/zXa3B92P1+MGFl+\nBBNU\r\n=qFQ+\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","gitHead":"99367ccf4fbbd2bc7f937f3266b54e80269b360f","scripts":{"test":"echo \"Error: no test specified\" && exit 1","build":"webpack --config webpack.prod.js","build-dev":"webpack --config webpack.dev.js --watch"},"_npmUser":{"name":"dokmic","email":"m@dokol.in"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git"},"_npmVersion":"6.4.1","description":"BloomReach Experience SDK for React","directories":{},"_nodeVersion":"10.10.0","dependencies":{"axios":"^0.18.0","jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"devDependencies":{"react":"^16.4.1","webpack":"^4.16.0","babel-core":"^6.26.3","webpack-cli":"^3.0.8","babel-loader":"^7.1.5","webpack-merge":"^4.1.3","babel-preset-env":"^1.7.0","babel-preset-react":"^6.24.1","clean-webpack-plugin":"^0.1.19"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.5.2_1565694994557_0.5665498553161383","host":"s3://npm-registry-packages"}},"0.6.0":{"name":"bloomreach-experience-react-sdk","version":"0.6.0","keywords":["bloomreach","sdk","react"],"author":{"name":"Bloomreach B.V."},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.6.0","maintainers":[{"name":"abogaart","email":"arthur.bogaart@bloomreach.com"},{"name":"ajbanck","email":"arent-jan.banck@bloomreach.com"},{"name":"br-mikedreynolds","email":"mike.reynolds@bloomreach.com"},{"name":"dokmic","email":"m@dokol.in"},{"name":"joerideg","email":"joerideg@gmail.com"},{"name":"jtsengyc","email":"jtsengyc@gmail.com"},{"name":"kenansalic","email":"kenan.salic@gmail.com"},{"name":"lachire","email":"charlie.chen@bloomreach.com"},{"name":"mdenburger","email":"mdenburger@gmail.com"},{"name":"michiel_eggermont","email":"michiel.eggermont@bloomreach.com"},{"name":"michielrop","email":"michiel.rop@bloomreach.com"},{"name":"mjmetter","email":"michael.metternich@bloomreach.com"},{"name":"mpalenov","email":"maxim.palenov@bloomreach.com"},{"name":"namendes","email":"namendes@gmail.com"},{"name":"pcentgraf-bloomreach","email":"peter.centgraf@bloomreach.com"},{"name":"sshepelevich","email":"sergey.shepelevich@bloomreach.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://issues.onehippo.com/projects/CMS"},"dist":{"shasum":"53273cd03a9cd0f156584b4bf54dfc495c78aebf","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.6.0.tgz","fileCount":31,"integrity":"sha512-//EjwVpZsOb0eROVqZ/BNVXFLYSHS0Jcxz5JnWHqn8s5z0Tbpa9n4yy/HmlyvtdCexvTT6SJ5UdCX2x9mm0cnQ==","signatures":[{"sig":"MEYCIQCJrHkfHVDGBiHNSaFdFOUDHO3zVyx9EDlRmWl1I1pqnwIhAIVxyiGEyys3ECSDb5P0DhMcDiAjoWrxp2muijL2J9+T","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":184035,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdeLhXCRA9TVsSAnZWagAA6zkP/0AtAiEBZB54WQ1ut22u\nNl8B9k+ybRDfh/9vanznKt948DG9CdY3b5QstxdkApH6/N+DmyFj3QkY/YhS\ny6taNmJrmMF55J2tSQlwtLn89FQHXAOaiB1M4MRt/1e4tNJae6B1fnxkORDF\nVrUMHsrD71ygH59Wb1HVFIMIkk/lpUWEx4gleswYYHDjAYHXQkiIRvORaIsj\nhjYn5gV9hHG5vRE/Cl7xhdt+qy8FXq87MJH/60MmzgRUOWNFsasHqMKMi9sD\nTA5o4dlMZ2aLd1F85ow5Xfzuk4wqHs0Q1rNppbhQ62gBgT43byxG0elggPAM\nAMCtHYzLqWtA6C19EZ3llEUw4fUYsXQpBOx9D6NacA1WSB9dcY+qdpPfeaLY\nU7Jm0am20SuX1ZUoWtKsa+BKsoyEBQfHm7ZffTCo9bEibwBzvm3pLcPB7iJB\nraGVCB26PIYV7aFSYKXRi2PzCRhD9XyXye2+6GAr5NIjF9JDJD6Dk6IE0uFt\nYrV2mlTZIzZGV7+mT/lYU0QOGQbU4gTSX8vRNL8ut/jxECyu8EI2zbNcf3Wt\nkGLQeYOGppj05gJtvzGB6rTZslYXJXbSn9X4Nd8nfNm5W69Ju1vybMSNjnPu\nVBcJLcp/8WkoVO3e3k2kglxupSOaQ8+TwPIQray0RFZZkmMx814HFQ9npGiO\nadf7\r\n=tITb\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","scripts":{"lint":"febuild lint:js","build":"rollup -c rollup.config.js"},"_npmUser":{"name":"dokmic","email":"m@dokol.in"},"repository":{"url":"https://github.com/bloomreach/experience-react-sdk","type":"git","directory":"packages/sdk"},"description":"Bloomreach Experience SDK for React","directories":{},"dependencies":{"axios":"^0.18.0","jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"devDependencies":{"react":"^16.8","rollup":"^1.17","@babel/core":"^7.5","@babel/preset-env":"^7.5","@babel/preset-react":"^7.0","eslint-plugin-react":"^7.14","rollup-plugin-babel":"^4.3","rollup-plugin-terser":"^5.1","@bloomreach/frontend-build":"^11.0","babel-plugin-transform-async-to-promises":"^0.8","@babel/plugin-proposal-object-rest-spread":"^7.5"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.6.0_1568192598277_0.2724454599021766","host":"s3://npm-registry-packages"}},"0.6.1":{"name":"bloomreach-experience-react-sdk","version":"0.6.1","keywords":["bloomreach","sdk","react"],"author":{"name":"Bloomreach B.V."},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.6.1","maintainers":[{"name":"abogaart","email":"arthur.bogaart@bloomreach.com"},{"name":"ajbanck","email":"arent-jan.banck@bloomreach.com"},{"name":"br-mikedreynolds","email":"mike.reynolds@bloomreach.com"},{"name":"dokmic","email":"m@dokol.in"},{"name":"joerideg","email":"joerideg@gmail.com"},{"name":"jtsengyc","email":"jtsengyc@gmail.com"},{"name":"kenansalic","email":"kenan.salic@gmail.com"},{"name":"lachire","email":"charlie.chen@bloomreach.com"},{"name":"michiel_eggermont","email":"michiel.eggermont@bloomreach.com"},{"name":"michielrop","email":"michiel.rop@bloomreach.com"},{"name":"mjmetter","email":"michael.metternich@bloomreach.com"},{"name":"mpalenov","email":"maxim.palenov@bloomreach.com"},{"name":"namendes","email":"namendes@gmail.com"},{"name":"pcentgraf-bloomreach","email":"peter.centgraf@bloomreach.com"},{"name":"shekhar.kumar","email":"shekhar.kumar@bloomreach.com"},{"name":"sshepelevich","email":"sergey.shepelevich@bloomreach.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://issues.onehippo.com/projects/CMS"},"dist":{"shasum":"cedfdf869c98ecf3a254f8d10129d2b23c9ae3d0","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.6.1.tgz","fileCount":25,"integrity":"sha512-ZDBQ3+wZ1BW+z4MVt0jmb+5RAaP4JND0R99ev3FEdEZ9R0ZXmfnJ0fy6fiqxm+Jnq1Q0e39TFG43mEL1uSzxXw==","signatures":[{"sig":"MEQCIBjXVG8U2ScX1WpNjqlcA7XZiZhre/NsUF978ci2A6mBAiA3LnKZp1oI+3NX8t+6eozzPxkoiZd3Dn7UXptEy/btAg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":184436,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdpdzzCRA9TVsSAnZWagAANKEQAISFOkOD6EAiNv5mi4fY\nFJy1FGrZ+HWCVj1YAi73W2pp/OTNva2tGr9q4czdg5R/Dsa9I0x/4GPpxTiP\nJlVXH7zTZWJc5j2G2DHwdVjwi+6io6SwF+cisdDP9GR6scYo+ruQvI3Oca3H\nqKMdJUemvUAsrmBhUXRsgqKJZvpq0GLLasUZd7uK6KNaS3SJ4vNoYXEmA0uG\nL1xhlI6rP7/Ql1/Uce74Tbw4j9vOoCPa7Ks1hQTxBcLRkSfVL7azzRmTXRQ8\n2IJHRVL650wnSKWzS/CqAeUBnWlpVDE32ocTUi2F3BHuil93yq6u2ixS50hs\ndRhIKj19+sY69jgAp8e4IROrscCJqAyuZ0KGgGdJTitbh/tmG2+r4DrEcIac\nQBjp+68QY6zma7f5fPfp5fvZYZfZLQwZ777u8CsPUDhGYLJC+8s+IefKwD2V\nCjEkuYAdhVFFbaNkB9Xe0YNeS0oXcBRtdHzuPU7/Z6Pa2LUcxv1s6eDSYDBd\nkckd4waB653V+95GrtwID+1lbNBEmlEvNB1GBdDCLaw+vIEHo8wNJQGa/8+9\n6evda+IMpSdVBpI6MpKQWpL4g0rLvEFW3coE2yVtXFt7wjupw8IAQk19LWoc\nsk0xWaue59yaf/Lj7XNHNJmGTKa5mTr5c1GGxyKOaYba8HrZJ8cdGDipU5qK\ng3F0\r\n=VSnl\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","_from":"file:bloomreach-experience-react-sdk-0.6.1.tgz","scripts":{"lint":"eslint src/ --format node_modules/eslint-formatter-friendly","build":"rollup -c rollup.config.js"},"_npmUser":{"name":"dokmic","email":"m@dokol.in"},"_resolved":"","_integrity":"","repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git","directory":"packages/sdk"},"_npmVersion":"6.10.3","description":"Bloomreach Experience SDK for React","directories":{},"_nodeVersion":"12.10.0","dependencies":{"axios":"^0.18.0","jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"devDependencies":{"react":"^16.8","eslint":"^6.3.0","rollup":"^1.17","@babel/core":"^7.5","@babel/preset-env":"^7.5","@babel/preset-react":"^7.0","eslint-plugin-babel":"^5.3.0","eslint-plugin-react":"^7.14","rollup-plugin-babel":"^4.3","eslint-plugin-import":"^2.18.2","rollup-plugin-terser":"^5.1","eslint-config-airbnb-base":"^14.0.0","eslint-formatter-friendly":"^7.0.0","babel-plugin-transform-async-to-promises":"^0.8","@babel/plugin-proposal-object-rest-spread":"^7.5"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.6.1_1571151091007_0.5332456302201933","host":"s3://npm-registry-packages"}},"0.6.2":{"name":"bloomreach-experience-react-sdk","version":"0.6.2","keywords":["bloomreach","sdk","react"],"author":{"name":"Bloomreach B.V."},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.6.2","maintainers":[{"name":"abogaart","email":"arthur.bogaart@bloomreach.com"},{"name":"ajbanck","email":"arent-jan.banck@bloomreach.com"},{"name":"br-mikedreynolds","email":"mike.reynolds@bloomreach.com"},{"name":"dokmic","email":"m@dokol.in"},{"name":"joerideg","email":"joerideg@gmail.com"},{"name":"jtsengyc","email":"jtsengyc@gmail.com"},{"name":"kenansalic","email":"kenan.salic@gmail.com"},{"name":"lachire","email":"charlie.chen@bloomreach.com"},{"name":"michiel_eggermont","email":"michiel.eggermont@bloomreach.com"},{"name":"michielrop","email":"michiel.rop@bloomreach.com"},{"name":"mjmetter","email":"michael.metternich@bloomreach.com"},{"name":"mpalenov","email":"maxim.palenov@bloomreach.com"},{"name":"namendes","email":"namendes@gmail.com"},{"name":"pcentgraf-bloomreach","email":"peter.centgraf@bloomreach.com"},{"name":"shekhar.kumar","email":"shekhar.kumar@bloomreach.com"},{"name":"sshepelevich","email":"sergey.shepelevich@bloomreach.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://issues.onehippo.com/projects/CMS"},"dist":{"shasum":"8faa5bd92bb62ed0e3d328cb705c0b2bd315302f","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.6.2.tgz","fileCount":25,"integrity":"sha512-7+GwIFJq55lu/U05YofwMcR6dbH+x51MdtsbdUeWKjRpJqkhvWnNuA0e9zkR0y1O1VTNaQ8rgjPtm2glAaXIIw==","signatures":[{"sig":"MEUCIA+KDiuAz0J6I5JyRJ0vtdVzrVQMQjcafbKRPfS4PNUnAiEA1AFa4g9TiuvHLYsA9/iQ5MSFXS5XltUUrtbhRlHZVPk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":184888,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd1u2ACRA9TVsSAnZWagAACNYQAKDyZisY2cxihvIXVh2O\n3gxRObshbnp210RhzzYP2Iql3Xjec7+RSVr6bVgza4TbI6P05WDlHNzyj31D\nNKy31zvHmlbCFhYMNv3ZZF1fQ9/8kxEXBaO7kd9B4G6blbem7dlroJShANDo\nC71HGP9TMLDiOTDGLiOZuLpnoQRpsYBvZ/BKZPi6f4PNRbLLNPponQJ7MPeX\nAnUaHm9obNM8aahzSe2l5TuW1lw0jkOflUIW6deX0+juJjlbuwRaf6gQo/6G\nin/HlJZsJ92ItU4G3GhmLqF0lXQWaj2JWSCzR9xSFoQYWmfcWSlqWBFAL9MB\nmUJD5UJ52CkaQeFDtXPQ8wN+Pxgq23+UPIt7sFAvBpfdG6aGUW4m64kca8EW\n1EYN6qupHHd+rEPHbVJabpWgKOq6ZnKMbgE6c4+se62sp145MTnCecqm3LB6\nDmJL3uwFnRZViSGsxZFbkLs2UVzjiNGednjXZ8kU4w3IeRK6e2su3OTlQ2ju\nfDKCHIKKVsgVgIeD7JQ63hHcuaHMOh/44gafWFqPp6Jn4SIoelSn+VaqiTyv\nfdMeLVd0n5PrEG+Ess3injnYC+A1UM1s/Rnc+8Z9o4swMBFx9ax+kCEnx4V4\nUL0weI3PqOyPINAD75givHPIyGixz+NhxJSLeyAmvFRfg5rOYf4SJrIcV5sj\nRYqD\r\n=4ejn\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","_from":"file:bloomreach-experience-react-sdk-0.6.2.tgz","scripts":{"lint":"eslint src/ --format node_modules/eslint-formatter-friendly","build":"rollup -c rollup.config.js"},"_npmUser":{"name":"dokmic","email":"m@dokol.in"},"_resolved":"","_integrity":"","repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git","directory":"packages/sdk"},"_npmVersion":"6.4.1","description":"Bloomreach Experience SDK for React","directories":{},"_nodeVersion":"8.15.1","dependencies":{"axios":"^0.18.0","jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"devDependencies":{"react":"^16.8","eslint":"^6.3.0","rollup":"^1.17","@babel/core":"^7.5","@babel/preset-env":"^7.5","@babel/preset-react":"^7.0","eslint-plugin-babel":"^5.3.0","eslint-plugin-react":"^7.14","rollup-plugin-babel":"^4.3","eslint-plugin-import":"^2.18.2","rollup-plugin-terser":"^5.1","eslint-config-airbnb-base":"^14.0.0","eslint-formatter-friendly":"^7.0.0","babel-plugin-transform-async-to-promises":"^0.8","@babel/plugin-proposal-object-rest-spread":"^7.5"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.6.2_1574366591417_0.05694793213791116","host":"s3://npm-registry-packages"}},"0.6.3":{"name":"bloomreach-experience-react-sdk","version":"0.6.3","keywords":["bloomreach","sdk","react"],"author":{"name":"Bloomreach B.V."},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.6.3","maintainers":[{"name":"abogaart","email":"arthur.bogaart@bloomreach.com"},{"name":"ajbanck","email":"arent-jan.banck@bloomreach.com"},{"name":"br-mikedreynolds","email":"mike.reynolds@bloomreach.com"},{"name":"dokmic","email":"m@dokol.in"},{"name":"drq","email":"drq@nxfinc.com"},{"name":"gijshendrix","email":"gijs.hendrix@bloomreach.com"},{"name":"joerideg","email":"joerideg@gmail.com"},{"name":"jtsengyc","email":"jtsengyc@gmail.com"},{"name":"kenansalic","email":"kenan.salic@gmail.com"},{"name":"lachire","email":"charlie.chen@bloomreach.com"},{"name":"michiel_eggermont","email":"michiel.eggermont@bloomreach.com"},{"name":"michielrop","email":"michiel.rop@bloomreach.com"},{"name":"mjmetter","email":"michael.metternich@bloomreach.com"},{"name":"mpalenov","email":"maxim.palenov@bloomreach.com"},{"name":"namendes","email":"namendes@gmail.com"},{"name":"nmendes","email":"namendes@gmail.com"},{"name":"pcentgraf-bloomreach","email":"peter.centgraf@bloomreach.com"},{"name":"shekhar.kumar","email":"shekhar.kumar@bloomreach.com"},{"name":"sshepelevich","email":"sergey.shepelevich@bloomreach.com"},{"name":"vlets","email":"georgevle93@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://issues.onehippo.com/projects/CMS"},"dist":{"shasum":"72bb47edecc429fa6542f3daef6d38817a871342","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.6.3.tgz","fileCount":25,"integrity":"sha512-EaltxZe1MvxLouW2A69S7W/s3suvMsqg85k5vHv/6Yn15TnS8b09QD0aHmmeI6z+yi19wN8g+iNbnwF84UNwCA==","signatures":[{"sig":"MEYCIQDux3TKvojorElkjFykJNXMyt1TQ7NbLhQgJtzm/fLH2wIhAK0Q/oVGlvfBkiCCflXcJlAWvljttKWE3VRpFxCkl1IF","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":185691,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeE1arCRA9TVsSAnZWagAAKKwP/1STCNG+NoIJL/myt7/1\nn9395Q7raE3u9nSW4BuACTKlPIas9P1EqDP6mfF2mliRx6CsGcYUoJTcyRZb\nN5uy7EOMPeD4G6x0qfK6Mas9z82t/SbePVAbqofS415g0GXYA6n06UwzPnNe\nlrXrca6xxqQusDZvXD3lnevPLTCuNujOBTQEH0XzH4Z2xivMuErxhd75tkP1\nDnITvMVvWJaNcal2CMQD5JPR/nWUz79Qyyo+bEkjVjEqg4qXxIIcoWelbeAp\n3fmZgC2sVKOmJrs7hDAPBGqDEXewpljGRRqP8YzUONMoa4PIOBB3FebcyAry\nDMWc+EHC3YtBj3mfJUsw8/n6Ej9ArZHMXZY8pVPk04UfB7vFRPp8OCVJpi3C\nIOcJ8w/eZSGAGyYu7phrkgHGNLq2By8W0mFmqXy4GScu7lbELPPPQv7QGdmy\n6Co5ywpVohOHntzXzxGZ9LmpDDO4DkE6F7e18GNCP9q5U2m+0N4HphyrgHk9\nrMET0V4KVEVbO5S83ldss0cDwnPq8t/do8aT8ewKWF7Yzj+9y9CVzK9rzuJh\nWszBy8nHSfCibnA1YPZhr8TpyL7HmEKIbX0Y8PpBVYmeSxSMlCNKRkrdUdJF\ncs+00kxuPvGpeE8gJBKQHfRBH8SaOGhzzYsMDbykaOgmVeK2hw8yulaGfsXE\nwKSi\r\n=/ZCo\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","scripts":{"lint":"eslint src/ --format node_modules/eslint-formatter-friendly","build":"rollup -c rollup.config.js"},"_npmUser":{"name":"dokmic","email":"m@dokol.in"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git","directory":"packages/sdk"},"_npmVersion":"6.13.4","description":"Bloomreach Experience SDK for React","directories":{},"_nodeVersion":"12.14.0","dependencies":{"axios":"^0.18.0","jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"devDependencies":{"react":"^16.8","eslint":"^6.7.2","rollup":"^1.27","@babel/core":"^7.7","@babel/preset-env":"^7.7","@babel/preset-react":"^7.7","eslint-plugin-babel":"^5.3.0","eslint-plugin-react":"^7.17","rollup-plugin-babel":"^4.3","eslint-plugin-import":"^2.19.1","rollup-plugin-terser":"^5.1","eslint-config-airbnb-base":"^14.0.0","eslint-formatter-friendly":"^7.0.0","babel-plugin-transform-async-to-promises":"^0.8","@babel/plugin-proposal-object-rest-spread":"^7.7"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.6.3_1578325674628_0.8526142737236633","host":"s3://npm-registry-packages"}},"0.6.4":{"name":"bloomreach-experience-react-sdk","version":"0.6.4","keywords":["bloomreach","sdk","react"],"author":{"name":"Bloomreach B.V."},"license":"Apache-2.0","_id":"bloomreach-experience-react-sdk@0.6.4","maintainers":[{"name":"abogaart","email":"arthur.bogaart@bloomreach.com"},{"name":"ajbanck","email":"arent-jan.banck@bloomreach.com"},{"name":"br-mikedreynolds","email":"mike.reynolds@bloomreach.com"},{"name":"brdroz","email":"josh.linder@gmail.com"},{"name":"davidboyd1","email":"david@davidboyd.com"},{"name":"dmartino11","email":"dmartino11@yahoo.com"},{"name":"dokmic","email":"m@dokol.in"},{"name":"drq","email":"drq@nxfinc.com"},{"name":"gijshendrix","email":"gijs.hendrix@bloomreach.com"},{"name":"joerideg","email":"joerideg@gmail.com"},{"name":"jtsengyc","email":"jtsengyc@gmail.com"},{"name":"kholmesbr","email":"kev.holmes@bloomreach.com"},{"name":"kpletcher","email":"kevin@bloomreach.com"},{"name":"michiel_eggermont","email":"michiel.eggermont@bloomreach.com"},{"name":"michielrop","email":"michiel.rop@bloomreach.com"},{"name":"mjmetter","email":"michael.metternich@bloomreach.com"},{"name":"mpalenov","email":"maxim.palenov@bloomreach.com"},{"name":"nmendes","email":"namendes@gmail.com"},{"name":"pauledwardsbloomreach","email":"paul.edwards@bloomreach.com"},{"name":"pcentgraf-bloomreach","email":"peter.centgraf@bloomreach.com"},{"name":"plenselink","email":"pieter.lenselink@Bloomreach.com"},{"name":"shekhar.kumar","email":"shekhar.kumar@bloomreach.com"},{"name":"smazza","email":"samantha.mazza@bloomreach.com"},{"name":"sshepelevich","email":"sergey.shepelevich@bloomreach.com"},{"name":"stefmz","email":"stefanos.maziotis@bloomreach.com"},{"name":"tom.washek","email":"tom.washek@bloomreach.com"},{"name":"vlets","email":"georgevle93@gmail.com"},{"name":"yvesv","email":"yvesviegen@gmail.com"}],"homepage":"https://github.com/bloomreach/experience-react-sdk","bugs":{"url":"https://issues.onehippo.com/projects/CMS"},"dist":{"shasum":"a2441e6534c4fde16a10626355a0951ee17bff73","tarball":"https://registry.npmjs.org/bloomreach-experience-react-sdk/-/bloomreach-experience-react-sdk-0.6.4.tgz","fileCount":25,"integrity":"sha512-XOvR9QPFT4ZHXNo0P9BBnWeWXbgPhpS+BzuXwhL4YmCinp51HYcmSjqAEeroD9Bl+hbTr/O8sSNaJ2/jRgs9Gg==","signatures":[{"sig":"MEQCICh74YcY10nxhSnX/wdEW6bWxj+w0w/371hGaYr85MR7AiB3jLLyO6mo6TKDam1XVSCydkRGu7QNc+ODG7qGYfd0aA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":186177,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh2k4DCRA9TVsSAnZWagAAM4gP/1DY469kTQy/T/jp5Qbt\nlOhE9tX7Hgtk2LQDvFPnaUC/JeqPWjhPIjQCuGLSumVt6s6ltygTXK3ORZhw\nt2R2rOpGrWFyTqmf/VxOo02eGypLm5zl4mFGDDAimZ7DJYNQlZvUf+ldmDUi\ndJ+mDIMEakwYjrZhgXv3kJnZd/B9X0Wbhle5ZYnWN5ojULTvjZv6ZPcamPtV\nCyhzPQYSCJC10KhUUGaGVXWRPU/t349R9CVlbqd1w5aMjsheVl02tjOg0e7E\nriaBbaX8kX0gJ6DZwT7w/1W0C1traFryS2aOLcZUcqGjON+IUtVPkLZxLe+j\n2utKmbGc2EFxT0u+j6ALYGe5OPlLPa9wHM1kN7mhDq9Vx3fUDxg9GSwhXhyX\nsj/Bem2/aSerHizxvPVrMPdNg1wRQeT6mVK3Vy5SL5XIijm0Husxdxh3to72\nBQ0G0Tjh67dumrd7/+HWsGHF4kcRK5PcxgoEvUircGXO+/SgMgfj1HLUxVRX\nKAdvyCJulp8SZvE7Dv6y9gW/2xvRq9LiaFOY9sgSDLH75KYujvL0TtF+OSEx\nc3YFadXqoMH0tvU0p0NwoU0phNmxIvsma0Ks+Tm/gjdWA/yXi56QgK5bWze/\niMtdTwglajhLJipwYEr9ocRHN02eQncqyIDwhUrq1JddZjo4sRwwifMbXrsD\nFJ9Y\r\n=E6fZ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"dist/bloomreach-experience-react-sdk.js","scripts":{"lint":"eslint src/ --format node_modules/eslint-formatter-friendly","build":"rollup -c rollup.config.js"},"_npmUser":{"name":"dokmic","email":"m@dokol.in"},"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git","directory":"packages/sdk"},"_npmVersion":"6.13.4","description":"Bloomreach Experience SDK for React","directories":{},"_nodeVersion":"12.16.1","dependencies":{"axios":"^0.18.0","jsonpointer":"^4.0.1","path-to-regexp":"^2.2.1","react-html-parser":"^2.0.2"},"_hasShrinkwrap":false,"devDependencies":{"react":"^16.8","eslint":"^6.7.2","rollup":"^1.27","@babel/core":"^7.7","@babel/preset-env":"^7.7","@babel/preset-react":"^7.7","eslint-plugin-babel":"^5.3.0","eslint-plugin-react":"^7.17","rollup-plugin-babel":"^4.3","eslint-plugin-import":"^2.19.1","rollup-plugin-terser":"^5.1","eslint-config-airbnb-base":"^14.0.0","eslint-formatter-friendly":"^7.0.0","babel-plugin-transform-async-to-promises":"^0.8","@babel/plugin-proposal-object-rest-spread":"^7.7"},"peerDependencies":{"react":"^16.2.0"},"_npmOperationalInternal":{"tmp":"tmp/bloomreach-experience-react-sdk_0.6.4_1583963333363_0.002137354494752275","host":"s3://npm-registry-packages"}}},"time":{"created":"2018-07-25T18:21:06.102Z","modified":"2026-09-04T10:07:37.304Z","0.1.0-rc1":"2018-07-25T18:21:06.163Z","0.1.0":"2018-07-25T18:43:05.319Z","0.1.1-rc1":"2018-07-25T19:34:53.491Z","0.1.1":"2018-07-25T19:59:47.074Z","0.1.2":"2018-08-01T14:10:52.709Z","0.2.0-rc1":"2018-08-16T20:59:54.565Z","0.2.0-rc2":"2018-08-22T16:07:43.572Z","0.2.0":"2018-08-30T13:52:57.844Z","0.2.1":"2018-09-14T13:27:26.196Z","0.3.0-rc1":"2018-09-14T21:43:59.004Z","0.4.0-rc1":"2018-09-16T21:12:11.674Z","0.4.1-rc1":"2018-09-20T01:46:20.051Z","0.4.1":"2018-09-28T20:55:46.614Z","0.4.2-rc1":"2018-09-28T21:04:43.472Z","0.4.3-rc1":"2018-09-29T16:30:17.344Z","0.4.4-rc1":"2018-10-04T02:49:57.022Z","0.4.5-rc1":"2018-10-10T20:01:09.695Z","0.4.4":"2018-11-02T18:58:53.139Z","0.4.5-rc3":"2018-12-05T19:01:06.368Z","0.4.5-rc4":"2018-12-05T19:29:05.784Z","0.4.5-rc5":"2019-01-30T15:01:52.637Z","0.5.0-rc1":"2019-05-23T14:38:46.703Z","0.5.1":"2019-08-02T12:55:16.230Z","0.5.2":"2019-08-13T11:16:34.707Z","0.6.0":"2019-09-11T09:03:18.472Z","0.6.1":"2019-10-15T14:51:31.233Z","0.6.2":"2019-11-21T20:03:11.629Z","0.6.3":"2020-01-06T15:47:54.796Z","0.6.4":"2020-03-11T21:48:53.500Z"},"bugs":{"url":"https://issues.onehippo.com/projects/CMS"},"author":{"name":"Bloomreach B.V."},"license":"Apache-2.0","homepage":"https://github.com/bloomreach/experience-react-sdk","keywords":["bloomreach","sdk","react"],"repository":{"url":"git+https://github.com/bloomreach/experience-react-sdk.git","type":"git","directory":"packages/sdk"},"description":"Bloomreach Experience SDK for React","maintainers":[{"email":"beetlerom@gmail.com","name":"beetlerom"},{"email":"joeri.degooijer@bloomreach.com","name":"joerideg"},{"email":"arthur.bogaart@bloomreach.com","name":"abogaart"},{"email":"rishabh.chhabda@bloomreach.com","name":"rishabh.chhabda"},{"email":"rameshkumar.arumugam@bloomreach.com","name":"rameshbr"},{"email":"peter.centgraf@bloomreach.com","name":"pcentgraf-bloomreach"},{"email":"georgevle93@gmail.com","name":"vlets"},{"email":"paul.edwards@bloomreach.com","name":"pauledwardsbloomreach"},{"email":"david@davidboyd.com","name":"davidboyd1"},{"email":"drq@nxfinc.com","name":"drq"},{"email":"nikola.trajkovski@bloomreach.com","name":"ntrajkovski"},{"email":"bcanvural@gmail.com","name":"bcanvural"},{"email":"charlie.chen@bloomreach.com","name":"lachire"},{"email":"giacomo.lamonaco@bloomreach.com","name":"glm-bloomreach"},{"email":"matteo.giusto@bloomreach.com","name":"mgiusto"},{"email":"bartosz.oudekerk@bloomreach.com","name":"boudekerk"},{"email":"aakash.anand@bloomreach.com","name":"aakash.anand"},{"email":"prateek.pandey@bloomreach.com","name":"prateek.pandey"},{"email":"jeroen.hoffman@bloomreach.com","name":"jeroenhoffman"},{"email":"vahid.mehrjouei@bloomreach.com","name":"vahid.mehrjouei"},{"email":"wenjun.li@bloomreach.com","name":"wenjun.li"},{"email":"shiva.dharavath@bloomreach.com","name":"shivanayak.dharavath2"}],"readme":"# BloomReach Experience SDK for React\n\n> The BloomReach Experience SDK for React works only with [Bloomreach Experience](https://www.bloomreach.com/en/products/experience-manager) version 13 and below. Please use [@bloomreach/react-sdk](https://www.npmjs.com/package/@bloomreach/react-sdk) with all the latest versions of Bloomreach Experience.\n\nSDK for powering content and components in React applications by [BloomReach Experience](https://www.bloomreach.com/en/products/experience). \nThis library makes integrating a React app with BloomReach Experience a breeze. It supports both \nclient-side- and server-side rendered/isomorphic React apps. \n\nBloomReach Experience allows you to use an external front-end such as React for rendering while still \nproviding a native-like authoring experience, such as integrated preview, in-context editing, drag & \ndrop, server-side personalization. For more information on this approach, see [A new approach to \nintegrating SPA's with WCM: Fixing what's wrong with headless integrations](https://www.bloomreach.com/en/blog/2018/03/a-new-approach-to-integrating-spas-with-wcm-fixing-what%E2%80%99s-wrong-with-headless-integrations.html).\n\n## Install\n\n```bash\nnpm install --save bloomreach-experience-react-sdk\n```\n\n## Usage\n\n```jsx\nimport React from 'react'\nimport { CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\nconst componentDefinitions = {\n  \"MyCustomComponent\": { component: MyCustomComponent }\n}\n\nclass MyApp extends React.Component {\n  render() {\n    const request = { hostname: window.location.hostname, path: window.location.pathname + window.location.search };\n    return (\n      <CmsPage componentDefinitions={componentDefinitions} request={request}>\n        <RenderCmsComponent />\n      </CmsPage>\n    )\n  }\n}\n```\n\nAt a minimum, `<CmsPage>` and `<RenderCmsComponent>` should be imported in the React app.\n\n`<CmsPage>` fetches the Page Model when it is not supplied as a prop (see section on server-side \nrendering); it fetches updates to the page model on component changes in the CMS; and it initializes and \nmanages state, and provides this as context to `<RenderCmsComponent>`. The `<CmsPage>` component can be \nput anywhere within the React App.\n\n`<RenderCmsComponent>` renders components based on the Page Model API response. It consumes the state \nfrom `<CmsPage>` and renders the container components and any content referenced from the components as \ncontained in the Page Model API response. The `<RenderCmsComponent>` should be nested within `<CmsPage>` \nand placed in the React app at the exact location where you want BloomReach Experience to control what \ncomponents and content is rendered.\n\n`<CmsPage>` takes two props: `componentDefinitions` and `request`.\n\nThe `request` prop is used to fetch the Page Model for the current page; and to detect whether \npreview mode is active so that meta-data for Channel Manager functionality (e.g. in-context editing) is \nincluded in the HTML, and consequently Channel Manager functionality is enabled.\n\nFinally, component definitions are supplied through the `componentDefinitions` prop. The component \ndefinitions tell `<RenderCmsComponent>` what React component to render by mapping these to the \n*hst:label* of a CMS catalog component.\n\n## Server-side rendering\n\nFor server-side rendering (e.g. using [Next.js](https://github.com/zeit/next.js)) you need to fetch the \nPage Model API server-side and supply it as a prop to `<CmsPage>`. Apart from this the usage is the same \nas with client-side rendering.\n\nThe helper function `getApiUrl()` can be used to generate the Page Model API URL using the current \nrequest.\n\nIt is important to pass cookies from the initial request and supply these with the request header of the \nPage Model API request. Otherwise you will get a 403 error in preview mode.\n\nFinally, to get preview to work for server-side rendered apps you can use a reverse proxy to route \nrequests from BloomReach's site preview to the React App-server. For more details, see section *3.2 \nServer-side apps* of the Hippo Lab: [Integrate a React application with BloomReach Experience](https://www.onehippo.org/labs/integrate-a-react-application-with-bloomreach-experience.html).\n\n```jsx\nimport fetch from 'isomorphic-unfetch'\nimport { getApiUrl, CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\n// setting pageModel to empty list instead of null value,\n// as otherwise the API will be fetched client-side again after server-side fetch errors\nlet pageModel = {}\n\nconst request = { hostname: req.headers.host, path: asPath }\nconst url = getApiUrl(request, {})\n// pass cookies of initial request for CMS preview\nconst response = await fetch(url, {headers: {'Cookie': req.headers.cookie}})\n\nif (response.ok) {\n  try {\n    pageModel = await response.json()\n  } catch (err) {\n    console.log(`Error! Could not convert response to JSON for URL: ${url}`)\n  }\n} else {\n  console.log(`Error! Status code ${response.status} while fetching CMS page data for URL: ${url}`)\n}\n```  \n\n## Example React apps\n\nThere are two example React apps available that use the SDK. One client-side rendered, and one \nserver-side rendered using [Next.js](https://github.com/zeit/next.js). You can find the [example apps on \nGithub](https://github.com/bloomreach/experience-react-sdk/tree/master/examples).\n\n## Creating custom components\n\nAny components that are supplied through the `compenentDefinitions` prop can be any type of valid React \ncomponent, including functional components. Props are passed to these components as context so that you \ncan access the components' configuration, content, etc. See more information below.\n\n### Props\n\nThe following props are passed to a component that is rendered by `<RenderCmsComponent>`:\n- `configuration` - `Object` component configuration. Contains the contributed models, raw parameters \n and resolved parameters. Content included in the component's model is not serialized as part of the \n component's configuration but in a separate content object, and a JSON Pointer reference is used to \n link to the actual content object. This is done to prevent content from being included multiple times \n in the API response when referenced multiple times on a page. \n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview mode is active based on current URL supplied through \n `request` prop of `<CmsPage>`.\n\nFor more information on the Page Model API response, see the [Swagger documentation](https://www.onehippo.org/library/concepts/spa-plus/page-model-api/swagger-api-documentation.html).\n\n### Example\n\n```jsx\nimport React from 'react'\nimport NewsItem from './news-item'\nimport { getNestedObject } from 'bloomreach-experience-react-sdk'\n\nexport default class NewsList extends React.Component {\n  render() {\n    const preview = this.props.preview\n    const pageModel = this.props.pageModel\n    const configuration = this.props.configuration\n\n    // return placeholder if no list is set on component\n    const list = getNestedObject(configuration, ['models', 'pageable', 'items'])\n    if (!list && preview) {\n      return (<p>Click to configure {configuration.label}</p>)\n    } else if (!list) {\n      // don't render placeholder outside of preview mode\n      return null\n    }\n\n    // build list of news articles\n    const listItems = list.map((listItem, index) => {\n      if ('$ref' in listItem) {\n        return (<NewsItem contentRef={listItem.$ref} pageModel={pageModel} preview={preview} key={index}/>)\n      }\n    })\n\n    return (\n      <div className=\"row\">\n        <div className=\"col-sm-12 news-list\">\n          {listItems}\n        </div>\n      </div>\n    )\n  }\n}\n```\n\n### Content components\n\nComponents that reference a single content-item (e.g. the Banner component) can use a convenient \nwrapper-class that looks up the content and passes it as a prop. See below.\n\nTo enable this, the property `wrapInContentComponent: true` has to be set on the component in the \n`componentDefinitions` prop. See `componentDefinitions` in the API section for more details.\n\n#### Props\n\n- `content` - `Object` raw content object that contains the content-item's fields and field-values. Any \n references to other content-items (e.g. images) are serialized as JSON Pointers.\n- `manageContentButton` - `React.Component` for placement and rendering of the [Manage Content Button](https://www.onehippo.org/library/concepts/component-development/render-manage-content-button.html)\n in preview mode in CMS.\n- `pageModel` - `Object` full Page Model API response.\n- `preview` - `Boolean` is *true* if preview is active based on current URL supplied through `request` \n prop of `<CmsPage>`.\n\n#### Example\n\n```jsx\nimport React from 'react'\n\nconst content = this.props.content;\nconst manageContentButton = this.props.manageContentButton;\n\nclass Banner extends React.Component {\n  render() {\n    return (\n      <div className=\"my-content-component\">\n        { manageContentButton && manageContentButton }\n        { content.title && content.title }\n      </div>)\n  }\n}\n```\n\n### Static CMS components\n\nStatic CMS components are components that are defined by developers / administrators and cannot be  \nmodified by users in the CMS. However, any content or site menus these components reference can be \nchanged by users in the CMS.\n\nSince `<RenderCmsComponent>` only renders container components (drag-and-drop components) by default, \nyou have to specify two additional properties in order to render a static CMS component: the `path` \nproperty to point to the relative path of the component, and `renderComponent` to specify which React \ncomponent to use for rendering the component. See the example below.\n\n```jsx\n<RenderCmsComponent path={'menu'} renderComponent={CmsMenu} />\n```\n\n### Containers\n\nContainers are being used to hold container items, which will be rendered by the SDK. Whenever it needs to customize a layout of those container items, it is possible also to pass a custom container component in `componentDefinitions`.\n\n#### Example\n```jsx\nimport React from 'react'\nimport { CmsPage, RenderCmsComponent } from 'bloomreach-experience-react-sdk'\n\nfunction MyCustomFooter(props) {\n  return (\n    <footer>\n      <div class=\"logo\">...</div>\n      { props.children }\n      <div class=\"copyright\">...</div>\n    </footer>\n  );\n}\n\nconst componentDefinitions = {\n  \"Footer Container\": { component: MyCustomFooter }\n}\n\n// ...\n\nclass MyApp extends React.Component {\n  render() {\n    return (\n      <CmsPage componentDefinitions={componentDefinitions}>\n        <RenderCmsComponent />\n      </CmsPage>\n    )\n  }\n}\n```\n\n### More component examples\n\nFor more detailed examples, see the components included in the [example applications](https://github.com/bloomreach/experience-react-sdk/tree/master/examples/client-side-rendered/src/components). \n\n### Helper functions\n\nAdditionally, there are a variety of helper functions available. See the examples below. For full \ndetails on the APIs, see the API section.\n\n```jsx\nimport { createLink, getImageUrl, getNestedObject, parseAndRewriteLinks, parseDate } from 'bloomreach-experience-react-sdk'\n\nconst link = createLink('ref', link, linkText, className)\nconst image = getImageUrl(content.image, this.props.pageModel, this.props.preview)\nconst list = getNestedObject(configuration, ['models', 'pageable', 'items', 0])\nconst contentHtml = parseAndRewriteLinks(content.content.value, this.props.preview)\nconst date = parseDate(content.date)\n```\n\n## API\n\n### `<CmsPage>`\n\nThe CmsPage component is a higher-order component that takes care of:\n- Fetching the Page Model for client-side rendering, when not supplied as a prop.\n- Fetching Page Model updates on component changes in the CMS.\n- Initializing and managing state, and providing this as context to `<RenderCmsComponent>`.\n\n#### Properties\n\n- `cmsUrls` - `Object` Override default CMS URL's. (Optional)\n- `componentDefinitions` - `object` Mapping of CMS catalog components to React components. Determines \n what component to render based from the Page Model. (Optional)\n- `createLink` - `Function` Called when creating internal links so that links can be constructed using \n the router library of the React app. (Optional)\n- `pageModel` - `Object` Supply Page Model as prop. Used for server-side-rendering where Page Model API \n is fetched server-side. When supplied, `CmsPage` will not fetch Page Model API on mount, only on \n component updates in CMS. (Optional)\n- `request` - `String` Current URL-path for determining if preview mode is active, and for fetching the \n Page Model for the page that is active. (Required)\n\n###### `cmsUrls` property\n\nProperty that allows you to override the default URL's for fetching the Page Model API. Typically you \nwill only have to define `scheme`, `hostname`, `port`, and `contextPath`. Input object takes the \nfollowing properties (all are optional):\n- `scheme` - `String` scheme (default: *http*)\n- `hostname` - `String` hostname (default: *localhost*)\n- `port` - `number` port number (default: *8080*)\n- `contextPath` - `String` site context-path (default: *site*)\n- `channelPath` - `String` path to the used channel, if channel is accessed through a subpath\n- `previewPrefix` - `String` preview-prefix used by CMS (default: *_cmsinternal*)\n- `apiPath` - `String` path to Page Model API as subpath (default: *resourceapi*)\n- `apiComponentRenderingUrlSuffix` - `String` (default: *?_hn:type=component-rendering&_hn:ref=*)\n\n###### `componentDefinitions` property\n\nMaps CMS catalog components to React components. Expects as input an object with `hst:label` of the CMS \ncomponents as keys and as value another object. The nested object has the mandatory property `component` \nwho's value maps the CMS component to a React component. See the example below:\n\n```js\nconst componentDefinitions = {\n  \"MyCustomCmsComponent\": { component: MyCustomReactComponent },\n  \"AnotherCmsComponent\": { component: AnotherReactComponent, wrapInContentComponent: true }\n};\n```\n\nAdditionally, the property `wrapInContentComponent: true` can be used for components that reference a \nsingle content-item. When this property is set on a component, it will be wrapped in a convenient \nwrapper class. See section *Content components*.\n\n##### `createLink` property\n\nCalled when creating internal links so that links can be constructed using the router library of the \nReact app. \n\nTakes `Function` as input. The function should return valid JSX and have three parameters:\n- `href` - `String` href of link\n- `linkText` - `Function` contains the HTML that is wrapped inside the link. Is a function so that it \n can include HTML.\n- `className` - `String` classnames to add to the link element\n\nFor example:\n```jsx\nconst createLink = (href, linkText, className) => {\n  return (<Link className={className} to={href}>{linkText()}</Link>)\n}\n```\n\n##### `pageModel` property\n\nPage Model can be supplied as a prop when using a server-side rendered / isomorphic React framework. \nWhen supplied, `<CmsPage>` will not fetch the Page Model API client-side. \n\n##### `request` property\n\nTakes `Object` as input with properties `hostname` and `path`, both of type `String`. The property \n`hostname` should contain the hostname for the current request (client-side this is \nwindow.location.hostname). The property `path` should contain the URL-path for the current request \n(client-side this is window.location.pathname);\n\n### `<RenderCmsComponent>`\n\nRenders a CMS component and all of its children using the Page Model supplied by `<CmsPage>`. Will \nrender the entire Page Model by default.\n\n#### Properties\n\n- `path` - `String` path to a component (static CMS component), container or container-item in the Page \n Model to render only that component and its children. If no path is supplied, entire Page Model will be \n rendered. \n- `renderComponent` - `React.Component` render a static CMS component using specified React component. \n Only works in combination with `path` property, which should specify path to the static CMS component. \n Site menus that are rendered this way can leverage the `<CmsEditButton>` component for rendering edit \n buttons in the CMS.\n\n#### Example\n\n```jsx\n<RenderCmsComponent path={'menu'} renderComponent={CmsMenu} />\n```\n\n### `<CmsEditButton>`\n\nInserts meta-data for either a content-item or site menu for placing an edit button in preview mode in \nthe CMS. Content-items that are rendered by a content component using `wrapInContentComponent: true` do \nnot need to use this component, but should use the `manageContentButton` prop that passes the meta-data.\n\n#### Properties\n\n- `configuration` - `Object` configuration of the site menu (not the component configuration containing \nthe menu) or the content-item object which has the `_meta` object in its root.\n- `preview` - `Boolean` toggle to prevent edit buttons from being rendered outside of preview.\n\n### `getApiUrl(request, [newCmsUrls])`\n\nHelper function for generating URL to the Page Model API for server-side fetching of the Page Model. \n\n#### Arguments\n\n- `request` - `Object` containing hostname and URL-path as properties `hostname` and `path` \n respectively. See the `request` property section above.\n- `newCmsUrls` - `Object` takes `cmsUrls` property as input to override default CMS URL's\n\n#### Return types\n\n`String` returns URL for fetching Page Model API\n\n### `createLink(linkType, link, linkText, className)`\n\nCreates a link to either a component or content-item itself or a referenced content-item (can be a \ndocument, image or asset) and returns the link as JSX.  \n\n#### Arguments\n\n- `linkType` - `String` type of link to create. Valid values are `self`, `ref` or `href`.\n  - `self` - Create link to the component or content-item itself. E.g. for a news-item in a news \n   overview.\n  - `ref` - Create link to a referenced content-item. E.g. for a banner.\n  - `href` -  Used by `parseAndRewriteLinks()` to create links using a href only.\n- `link` - `Object` the component configuration or content-object that is linking to itself or \n referenced another content-item.\n- `linkText` - `JSX | Function` HTML to wrap inside the link. Is a function so that it can include HTML.\n- `className` - `String` classnames to add to the link element\n\n#### Return types\n\n`JSX` returns link as JSX object that can be included as a variable anywhere within the return section \nof a React component's render method.\n\n### `getImageUrl(imageRef, pageModel, preview)`\n\nCreates link to URL of image in case BloomReach Experience is used for serving images.\n\n#### Arguments\n\n- `imageRef` - `String` JSON Pointer that references the image.\n- `pageModel` - `Object` since this function is a pure JavaScript function it can't get Page Model from \n context, so it has to be provided as function parameter. The Page Model is used to retrieve the image.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by \n `<RenderCmsComponent>` can pass the prop `this.props.preview`.\n\n#### Return types\n\n`String` returns URL to image.\n\n### `getNestedObject(nestedObject, pathArray)`\n\nReturns a nested object or value using a path array. Useful when you need to access deeply nested \nobjects/values without having to string null checks together.\n\n#### Arguments\n\n- `nestedObject` - `Object` the object containing the nested object or value.\n- `pathArray` - `Array` contains the path to the nested object as an array.\n\n#### Return types\n\n`Object|null` returns the nested object if found, otherwise returns null. \n\n### `parseAndRewriteLinks(html, preview)`\n\nParses HTML of a rich-text field of a content-item for rewriting links in HTML to internal links. Uses \nthe `createLink` function passed to `<CmsPage>` for constructing internal links.\n\n#### Arguments\n\n- `html` - `String` value of rich-text field of a content-item. Should contain HTML only.\n- `preview` - `Boolean` toggle for whether preview mode is active. Components rendered by \n `<RenderCmsComponent>` can pass the prop `this.props.preview`.\n\n#### Return types\n\n`JSX` returns parsed and rewrited HTML as JSX.\n\n### `parseDate(date)`\n\nParses date-field of a content item and returns date as a string.\n\n#### Arguments\n\n- `date` - `String` takes raw value of a date-field as input, following the ISO 8601:2000 format.\n\n#### Return types\n\n`String` returns date in full date format.\n\n## Release notes\n\n### Version 0.6.4\n- Fix bug in the object type check in the `findChildById` function.\n\n### Version 0.6.3\n- Add support of fully-qualified resource links.\n\n### Version 0.6.2\n- Fixed page model fetch on the component update.\n\n### Version 0.6.1\n- Fixed a bug with query string passing to the Page Model API.\n- Fixed a bug with missing key prop in the link rewriter.\n\n### Version 0.6.0\n- Added eslint.\n- Migrated to rollup.\n- Migrated to yarn.\n- Fixed CmsPage children to not be wrapped around a function.\n- Added support of custom React components for container components.\n\n### Version 0.5.2\n- Fixed bug with query string affecting on the path parsing.\n\n### Version 0.5.1\n- Fixed bug with preview update on the component properties dialog changes;\n- Fixed bug with preview update on save/discard changes from the component properties dialog;\n- Fixed bug with the manage content button keeps referring to the old content after saving changes in the dialog.\n\n### Version 0.5.0\n- Fixed bug with SSO handshake in client-side rendered applications.\n\nUpgrade steps:\n- Pass query string parameters along with other request details to `<CmsPage>`:\n  ```jsx\n  const request = { hostname: window.location.hostname, path: window.location.path + window.location.search };\n  <CmsPage componentDefinitions={componentDefinitions} request={request}>\n  ```\n\n### Version 0.4.0\n\nAdded support for rendering static CMS components.\n- Added new property `renderComponent` to `<RenderCmsComponent>` which allows you to render a static \n component. This only works in combination with the `path` property, which should contain the relative \n path to the component.\n- Renamed `<ManageContentButton>` to `<CmsEditButton>` and exported it so it can be used by apps. This \n component is now more generic so it can also be used to generate edit buttons in the CMS for site menus.\n- Moved `<CmsMenu>` component out of SDK and into the example apps.\n\n\n### Version 0.3.0\n\nAdded extra checks so that `<div>` elements needed for CMS preview are only inserted in preview mode.\n\n### Version 0.2.0\n\nThis version includes significant changes. Please make sure to update your components using the upgrade \nsteps further down.\n- Changed `cmsUrls` property to support different live and preview URLs.\n- Changed `urlPath` property to `request` property which no longer takes URL-path as string, but an \n object with hostname and URL-path. This property should be passed to `<CmsPage>`.\n- Changed helper method `getApiUrl()` to take `request` property as parameter instead of `urlPath`.\n- Changed helper method `parseAndRewriteLinks()` to take an extra parameter: `preview`.\n- Changed helper method `getImageUrl()` to take an extra parameter: `preview`.\n\nUpgrade steps:\n- Modify `cmsUrls` property to include URLs for live and preview using the properties `live` and \n `preview` respectively. Please note that the `cms` prefix has been removed from all URL properties. So `cmsHostname` has become `hostname`. Preview URLs are optional. For example:\n  ```js\n  const cmsUrls = {\n    live: {\n      hostname: bloomreach.com\n    },\n    preview: {\n      hostname: cms.bloomreach.com\n    }\n  }\n  ```\n- Pass current request details through `request` property to `<CmsPage>`. This was previously done \n through the `urlPath` property. The `request` property should be an object that contains the hostname \n and path as properties `hostname` and `path` respectively. For example:\n  ```jsx\n  const request = { hostname: window.location.hostname, path: window.location.path };\n  <CmsPage componentDefinitions={componentDefinitions} request={request}>\n  ```\n- Update usage of `getApiUrl` to pass `request` property (see previous bullet) instead of URL-path.\n- Update usage of helper methods `getImageUrl()` and `parseAndRewriteLinks()` to include the preview \n parameter. Components rendered by `<RenderCmsComponent>` have the preview value passed as prop \n `this.props.preview`.\n\n## FAQ / Troubleshooting\n\n- Information about common problems and possible solutions can be found on [the troubleshooting page](https://documentation.bloomreach.com/library/concepts/spa-plus/sdk/spa-sdk-troubleshooting.html).\n- Information about the recommended setup can be found on [the best practices page](https://documentation.bloomreach.com/library/concepts/spa-plus/sdk/spa-sdk-best-practices.html).\n\n## License\n\nApache 2.0\n","readmeFilename":"README.md"}