Upgrade to Bloomreach Experience Manager React SDK 14
This documentation guides you in migrating your React project from bloomreach-experience-react-sdk for Bloomreach Experience Manager 13 to @bloomreach/react-sdk for Bloomreach Experience Manager 14.
Configuration
Before you can proceed with your code upgrade, you need to configure @bloomreach/react-sdk first.
- Install @bloomreach/react-sdk into your project.
- Update your environment configuration in the .env file according to this documentation.
For create-react-app based applications:PUBLIC_URL=http://localhost:3000 REACT_APP_LIVE_BR_BASE_URL=http://localhost:8080/site/spa-channel REACT_APP_LIVE_SPA_BASE_URL= REACT_APP_PREVIEW_BR_BASE_URL=http://localhost:8080/site/_cmsinternal/spa-channel REACT_APP_PREVIEW_SPA_BASE_URL=/site/_cmsinternal/spa-channel?bloomreach-preview=true
Or for Next.js applications:PUBLIC_URL=http://localhost:3000 LIVE_BR_BASE_URL=http://localhost:8080/site/spa-channel LIVE_SPA_BASE_URL= PREVIEW_BR_BASE_URL=http://localhost:8080/site/_cmsinternal/spa-channel PREVIEW_SPA_BASE_URL=/site/_cmsinternal/spa-channel?bloomreach-preview=true
- Update the URL Rewriter module configuration to be aligned with this document.
Code Changes
Since @bloomreach/react-sdk is a different library with its own API, you need to update your application code. You can do that by following instructions from the code snippets below.
Application Component
Before:
import { CmsPage } from 'bloomreach-experience-react-sdk'; const cmsUrls = { preview: { hostname: '127.0.0.1', port: 9080, channelPath: 'spa-channel', }, live: { hostname: 'localhost', port: 9080, channelPath: 'spa-channel', }, }; const componentDefinitions = { Banner: { component: Banner, wrapInContentComponent: true }, Content: { component: Content, wrapInContentComponent: true }, }; const request = { hostname: window.location.hostname, path: window.location.pathname + window.location.search }; return <CmsPage componentDefinitions={componentDefinitions} cmsUrls={cmsUrls} request={request} createLink={createLink} />;
After:
import { BrPage } from '@bloomreach/react-sdk'; const configuration = { httpClient: axios, options: { live: { cmsBaseUrl: process.env.REACT_APP_LIVE_BR_BASE_URL, spaBaseUrl: process.env.REACT_APP_LIVE_SPA_BASE_URL, }, preview: { cmsBaseUrl: process.env.REACT_APP_PREVIEW_BR_BASE_URL, spaBaseUrl: process.env.REACT_APP_PREVIEW_SPA_BASE_URL, }, }, request: { path: `${window.location.pathname}${window.location.search}`, }, }; const mapping = { Banner, Content }; return <BrPage configuration={configuration} mapping={mapping} />;
Inline Rendering
Before:
import { RenderCmsComponent } from 'bloomreach-experience-react-sdk'; <RenderCmsComponent path="menu" renderComponent={CmsMenu} />
After:
import { BrComponent } from '@bloomreach/react-sdk'; <BrComponent path="menu"> <Menu /> </BrComponent>
Components Rendering
Before:
import { RenderCmsComponent } from 'bloomreach-experience-react-sdk'; <RenderCmsComponent />
After:
import { BrComponent } from '@bloomreach/react-sdk'; <BrComponent />
Component
Before:
const { content, manageContentButton, preview } = props; return ( <div className={`jumbotron ${preview ? 'has-edit-button' : ''}"> { manageContentButton } { content.title && <h1>{content.title}</h1> } <div> );
After:
import { BrManageContentButton } from '@bloomreach/react-sdk'; const { document: documentRef } = props.component.getModels(); const document = documentRef && props.page.getContent(documentRef); if (!document) { return null; } const { title } = document.getData(); return ( <div className={`jumbotron ${props.page.isPreview() ? 'has-edit-button' : ''}`}> <BrManageContentButton content={document} /> { title && <h1>{title}</h1> } </div> );
Menu Component
Before:
import { CmsEditButton, getNestedObject } from 'bloomreach-experience-react-sdk'; const { configuration, preview } = this.props; if (!getNestedObject(configuration, ['models', 'menu', 'siteMenuItems', 0])) { return null; } const menuConfiguration = getNestedObject(configuration, ['models', 'menu']); return ( <ul className="navbar-nav"> { preview ? <CmsEditButton configuration={menuConfiguration} preview={preview} /> : null } </ul> );
After:
import { BrManageMenuButton } from '@bloomreach/react-sdk'; const { menu } = props.component.getModels(); return ( <ul className={`navbar-nav ${props.page.isPreview() ? 'has-edit-button' : ''}`}> <BrManageMenuButton menu={menu} /> </ul> );
Menu Link
Before:
import { createLink } from 'bloomreach-experience-react-sdk'; return ( <li className="nav-item"> { createLink('self', configuration, 'Link Text', 'link-class') } </li> );
After:
return ( <li className="nav-item"> <a href={props.page.getUrl(item._links.site)} className="link-class">Link Text</a> </li> );
Resource Link
Before:
import { getImageUrl } from 'bloomreach-experience-react-sdk'; const { content, pageModel, preview } = props; const image = getImageUrl(content.image, pageModel, preview); return ( <div> { image && <img src={image} alt={content.title} /> } </div> );
After:
const { document: documentRef } = props.component.getModels(); const document = documentRef && props.page.getContent(documentRef); if (!document) { return null; } const { image: imageRef, title } = document.getData(); const image = imageRef && props.page.getContent(imageRef); return ( <div> { image && <img src={image.getUrl()} alt={title} /> } </div> );
Content Links
Before:
import { parseAndRewriteLinks } from 'bloomreach-experience-react-sdk'; const { content, preview } = props; return ( <div> { parseAndRewriteLinks(content.content.value, preview) } </div> );
After:
const { document: documentRef } = props.component.getModels(); const document = documentRef && props.page.getContent(documentRef); if (!document) { return null; } const { content } = document.getData(); return <div dangerouslySetInnerHTML={{ __html: props.page.rewriteLinks(content.value) }} />;
Date Parsing
Before:
import { parseDate } from 'bloomreach-experience-react-sdk'; const { content } = props; return ( <div> { parseDate(content.date) } </div> );
After:
const { document: documentRef } = props.component.getModels(); const document = documentRef && props.page.getContent(documentRef); if (!document) { return null; } const { date } = document.getData<DocumentData>(); return ( <div> { new Date(date).toDateString() } </div> );