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.

  1. Install @bloomreach/react-sdk into your project.
  2. 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
  3. 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>
);
Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?