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>
);