React4XP - API reference

Contents

React4XP - API reference

The react4xp library (Enonic Market) exposes a couple of methods that can be run from XP controllers.

Install

Instructions on how to install the library locally or insert it into your project are at the library docs at github.

Import library

In an XP controller:
const React4xp = require('/lib/enonic/react4xp');


React4xp.render

All-in-one (static) shorthand function for a lot of use cases. Covers both client- and serverside rendering.

Inserts a react component into an (optional) pre-existing HTML string and adds any necessary page contributions to make all work: links to assets, both shared and specific to the entry, and a client-side JS call (.render or .hydrate in the client wrapper) that activates the react component in the browser.


Signature

The signature is analogous to thymeleaf’s familiar render(view, model). But there are two extra parameters, and a full XP response object is returned:

{body, pageContributions} = React4xp.render(entry, props, request, options);


Parameters

Name Type Description

entry

string or component object, mandatory

Reference to an entry: the react component to be rendered. JsxPath reference - or if the entry is a JSX file with the same name in the same folder as the controller, you can use a portal.getComponent() object here. Corresponds to the template argument in thymeleaf.render.

props

object, optional

Data model passed into the react component. JS object must be serializable (no functions can be passed). Corresponds to the model argument in thymeleaf.render.

request

XP request object, optional (but mandatory for react activation)

Include to detect the rendering mode inside/outside Content Studio: inside Content Studio there should be only a static serverside-rendering, no browser react activation (or client-side rendering), only returning get an HTML visualization with the initial props. Special case: if request is not an object but omitted/falsy, page-contributions rendering is completely skipped. In this case, the options argument (below) is still valid: any added body there will still serve as a container for the rendered output from this call, and any pageContributions inside options are still added and returned.

options

object, optional

Additional options to control the rendering. All of them are optional within this object:

Properties
Name Type Default Description

id

string

Generated unique string

ID of the component, targeting the ID of an element in body (below): react will render into that container element. Should be a unique ID within the entire HTML document.

If no matching element ID is found in body, this sets the ID of a generated element in the HTML output. If id is missing, a unique ID is generated, either random or generated from the content.

body

string: valid HTML

<div> with matching id

HTML to serve as container for the react content. Can be a hardcoded string, come from a thymeleaf/mustache/XSLT render, or any source. When server-side rendering, the rendered output will be inserted into the matching-id element inside here (replacing whatever was already in that element), and everything (container body with rendered content in it) is returned as one HTML string. When client-side rendering, this insertion happens in the browser.

If no body is supplied, an empty <div> element with an ID matching id is generated and used as container.

If a body is supplied but it doesn’t contain any element with a matching id, an extra matching-id <div> element will be generated and inserted into body - as a child of the root element of body and after any other content that’s already there.

pageContributions

object: valid XP page contributions

If you already have some page contributions you want to add to the output of this rendering, add them here. These added page contributions will be added before the ones that will be rendered (within each section headBegin, bodyEnd etc).

clientRender

boolean

false

Switch between clientside and servierside rendering, on this particular rendering. Other renderings are not affected, even within the same controller or using the same entry more than once.

If false / falsy or omitted, you get serverside rendering and the returned object will contain an HTML representation of the react component with the initial props, and page contributions will make the client call .hydrate.

If true / truthy, the server-side rendering is skipped for this particular rendering. The client will call .render.

This only applies in live mode and previews: inside edit or browse modes in Content Studio, you still only get a static server-side rendered representation).


Returns

Returns an XP response object with these main attributes:

Attribute Type Description

body

string, rendered HTML

HTML output.

The root of this HTML is always a surrounding container HTML that will have a matching-ID target element in it somewhere (an element matching the ID of the clientside call to .render or .hydrate: that ID is options.id if that was set, or a generated unique one if not). This surrounding structure is options.body, unchanged if that already contained a matching-ID element, or with a new target element generated and inserted at the end if it didn’t have one. If there is no options.body, the surrounding container is just a generated target <div> element.

Inside that matching-ID element, there will be a serverside rendering of the entry (with the initial props from options.props) if options.clientRender is falsy.

pageContributions

object

Regular XP page contributions. Includes everything the browser needs to activate (or client-side render) the react component: script tags with urls to auto-compiled assets for the entry and its dependencies, a client-side react4xp wrapper asset and an activating client-wrapper call. Urls point to react4xp’s own optimized asset services. Also included before this, are any input options.pageContributions.


Examples

Most of the lessons in the guide use React4xp.render (except the "custom flow" ones). For example here or here.




React4xp object

Slightly more cumbersome than React4xp.render, but also more flexible and controllable: create a data-holding react4xp object with the React4xp contructor, manipulate it or extract data from it, and then later render it to an HTML body string and/or page contributions, separately. This is actually what React4xp.render does behind the scenes.

The "custom flow syntax" lesson focuses on using react4xp data objects.



Constructor

const myComponent = new React4xp(entry);

Creates an initial react4xp data object from an entry.

Parameter Type Description

entry

string or component object, mandatory

Reference to an entry: the react component to be rendered. Direct JsxPath string, or a portal.getComponent() object. If you use a component object like that, the entry must be a JSX file with the same name in the same folder as the controller, and react4xp will try to generate an ID from the content.

Constructs a react4xp data object, which exposes the attributes and methods below:



Main object attributes

Extract from the object the data that has been generated or set in it.

Name Type Description

react4xpId

string

Target id of the HTML element the entry will be rendered into (if it’s been set yet - see setId and uniqueId below). Also identifies the object.

jsxPath

string

jsxPath to the entry.

props

object

props for the entry’s initial rendering. At the time of rendering, an attribute react4xpId is added to the props, allowing each entry to access its own unique ID at runtime.

Example:
const targetElementId = myComponent.react4xpId;



Setter methods

Use these to set the object’s properties. All of them are optional; if not used, the object will render with empty values or placeholders where needed, along the same logic as for React4xp.render above.

All the setter methods return the data object itself, so that you can use a builder pattern where…​

myComponent.firstSetter("a").secondSetter("b").thirdSetter("c");

…​is equivalent to:

myComponent.firstSetter("a");
myComponent.secondSetter("b");
myComponent.thirdSetter("c");

The order between the setters doesn’t matter, with the exception if setId and uniqueId which affect each other.


.setProps

myComponent.setProps(props);

Sets props for the entry.

Parameter Type Description

props

object, mandatory

props passed into the react component for initial rendering. JS object must be serializable (no functions can be passed).


.setId

myComponent.setId(id);

Sets an ID (directly and literally, so uniqueness is up to you) of both the target HTML element for rendering the entry into, and the ID of the data object itself (react4xpId). If renderBody() is run later without finding a matching element ID in body, this sets the ID of a generated element in the HTML output.

If the data object already has an ID, .setId(id) will overwrite it. If id is omitted, .setId() just deletes any previous ID (which has the later effect of giving this a new, unique ID at the time of rendering).

Parameter Type Description

id

string, optional

ID of both the target HTML element and the data object itself.


.uniqueId

myComponent.uniqueId();

Enforces a unique ID, either by itself or after running .setId(). If the object already has an ID (react4xpId), a random-ID string will be added to it. If not, the ID will just be a new random ID.

No parameters.


.setJsxPath

myComponent.setJsxPath(jsxPath);

If you for some reason need to override the JsxPath that was set (or inferred from the component object) in the constructor.

Parameter Type Description

jsxPath

string, mandatory

New jsxPath to a different entry.



Rendering methods

These methods perform specific rendering tasks independently, using the data object as a basis, the way it’s set up with the setters and with the entry from the constructor (or the setJsxPath setter).

Most of these rendering methods will lock down the jsxPath and ID if the react4xp data object, the first time one of them is run. After this, the setters will prevent these from being changed so that another conflicting rendering can’t be performed from the same data object.



.renderBody

const responseBody = myComponent.renderBody(options);

Similar to React4xp.render above, but renders only a static HTML output.

Renders based on the state of the data object at the time of rendering, and with fewer option parameters than React4xp.render.

The static HTML will always contain a target element for rendering the entry into. That target element contains a serverside rendering of the entry if serverside is switched on (clientRender is falsy).

Does not render page contributions. Run .renderPageContributions from the same data object, or the rendering will not be active in the browser.

Parameters:

Parameter Type Description

options

object, optional

Options to control the rendering, all of them optional:

Properties
Name Type Default Description

body

string: valid HTML

<div> with matching id (same as react4xpId in the data object)

Same as the options.body in React4xp.render above.

clientRender

boolean

false

Switch between clientside and serverside rendering, on this particular rendering.

Other renderings are not affected, even from the same data object (so you usually want to make sure a different rendering from the same data object uses the same mode).

Returns:

Returns an HTML string ready to return as the body attribute in an XP response object from the controller.

The root of the returned HTML is always a surrounding container HTML that will have a matching-ID target element in it somewhere (an element matching the data object’s ID (react4xpId), either from the ID setter methods, or a generated ID if they haven’t been run). This surrounding structure is options.body, unchanged if that already contained a matching-ID element, or with a new target element generated and inserted at the end if it didn’t have one. If there is no options.body, the surrounding container is just a generated target element.

Inside that matching-ID element, there will be a serverside rendering of the entry (with the initial props from .setProps) if options.clientRender is falsy.



.renderPageContributions

const outputPageContributions = myComponent.renderPageContributions(options);

Similar to React4xp.render above, but only renders the page contributions needed to run and activate the react component in the browser. Whether the trigger call is .render or .hydrate depends on if options.clientRender is truthy or falsy, respectively.

Renders based on the state of the data object at the time of rendering, and with fewer option parameters than React4xp.render.

Does not render any HTML. Run .renderBody from the same data object, or the browser may have nothing to activate / nowhere to render the entry.

Also, there is no detection of inside-vs-outside Content Studio, and consequently the client is not automatically prevented from running client-side code in Content Studio. That is not recommended, see the examples for how to handle this.

Parameters:

Parameter Type Description

options

object, optional

Options to control the rendering, all of them optional:

Properties
Name Type Default Description

pageContributions

object: valid XP page contributions

empty object

If you already have some page contributions you want to add to the output of this rendering, add them here. These added page contributions will be added before the ones that will be rendered (within each section headBegin, bodyEnd etc).

clientRender

boolean

false

Switch between clientside and servierside rendering, on this particular rendering.

Other renderings are not affected, even from the same data object (so you usually want to make sure a different rendering from the same data object uses the same mode).

Returns:

A regular XP page contributions object, ready to be used as the pageContributions attribute in an XP response object from the controller.

Includes everything the browser needs to activate (or client-side render) the react component: script tags with urls to auto-compiled assets for the entry and its dependencies, a client-side react4xp wrapper asset and an activating trigger call to the client wrapper. Urls point to react4xp’s own optimized asset services. Also included before this, are any input options.pageContributions.

With a serverside rendering (options.clientRender is falsy), the client will expect an existing target element with a pre-rendered entry in the response body, and call react4xp.CLIENT.hydrate. If options.clientRender is truthy, an empty target element is expected in the response body, and the rendering is left to the client with react4xp.CLIENT.render.



.renderEntryToHtml

const entryHTML = myComponent.renderEntryToHtml(overrideProps);

Helper rendering tool, for utility purposes.

Pure serverside rendering of the entry to a static HTML string, without any surrounding HTML, target container or anything, just the entry.

Parameter Type Description

overrideProps

object, optional

If omitted, the data object’s own props (from .setProps, if it’s been run) are used for the rendering. If overrideProps are included, however, the data object’s own props are ignored, and overrideProps used instead.

JS object must be serializable (no functions can be passed).

Returns a static HTML representation of the entry.



.renderTargetContainer

const targetContainerHTML = myComponent.renderTargetContainer(body, content);

Helper rendering tool, for utility purposes.

Generates a matching-ID target container based on the ID (react4xpId) of the react4xp object, intended for an entry to be rendered into later.

Parameter Type Description

body

string, optional: valid HTML

Similar to options.body in React4xp.render above: HTML to serve as a container for a react content.

If body is omitted, an empty target <div> element (with an ID matching that of the react4xp object, react4xpId) is generated and returned.

If body is supplied but doesn’t contain any element with an ID matching react4xpId, an extra target element <div> is generated and inserted into body before it all is returned - as the last child of the root element of body.

content

string, optional

If included, this is inserted into the target element in the output. (Note that if you later perform a react rendering into the target element, any content will be overwritten)

Returns an HTML representation that will contain a matching-ID target element, which (depending on body and content) may be surrounded by other HTML and/or have a content of its own.



Examples

Usage in a controller specifically is demonstrated here.

Contents