Fixed components provide some flexibility for authoring SPA content, however this approach is rigid and requires developers to define the exact composition of the editable content. To support the creation of exceptional experiences by authors, SPA Editor supports the use of container components in the SPA. Container components allow authors to drag and drop allowed components into the container, and author them, just like they can in traditional AEM Sites authoring!
In this chapter, we’ll add an editable container to the home view allowing authors to compose and layout rich content experiences using AEM React Core Components directly in the SPA.
To add a container component to the Home view:
To place an editable area to the Home view, we must:
@adobe/aem-react-editable-components
withMappable
so developers can place it in the SPAMapTo
so it can be reused in other Container components, effectively nesting containers.To do this:
Open the SPA project in your IDE
Create a React component at src/components/aem/AEMResponsiveGrid.js
Add the following code to AEMResponsiveGrid.js
// Import the withMappable API provided bu the AEM SPA Editor JS SDK
import { withMappable, MapTo } from '@adobe/aem-react-editable-components';
// Import the base ResponsiveGrid component
import { ResponsiveGrid } from "@adobe/aem-react-editable-components";
// The sling:resourceType for which this Core Component is registered with in AEM
const RESOURCE_TYPE = "wcm/foundation/components/responsivegrid";
// Create an EditConfig to allow the AEM SPA Editor to properly render the component in the Editor's context
const EditConfig = {
emptyLabel: "Layout Container", // The component placeholder in AEM SPA Editor
isEmpty: function(props) {
return props.cqItemsOrder == null || props.cqItemsOrder.length === 0;
}, // The function to determine if this component has been authored
resourceType: RESOURCE_TYPE // The sling:resourceType this SPA component is mapped to
};
// MapTo allows the AEM SPA Editor JS SDK to dynamically render components added to SPA Editor Containers
MapTo(RESOURCE_TYPE)(ResponsiveGrid, EditConfig);
// withMappable allows the component to be hardcoded into the SPA; <AEMResponsiveGrid .../>
const AEMResponsiveGrid = withMappable(ResponsiveGrid, EditConfig);
export default AEMResponsiveGrid;
The code is similar AEMTitle.js
that imported the AEM Reach Core Components’ Title component.
The AEMResponsiveGrid.js
file should look like:
Now that AEM’s ResponsiveGrid component is registered in and available for use within the SPA, we can place it in the Home view.
Open and edit react-app/src/App.js
Import the AEMResponsiveGrid
component and place it above the <AEMTitle ...>
component.
Set the following attributes on the <AEMResponsiveGrid...>
component
pagePath = '/content/wknd-app/us/en/home'
itemPath = 'root/responsivegrid'
This instructs this AEMResponsiveGrid
component to retrieve its content from the AEM resource:
/content/wknd-app/us/en/home/jcr:content/root/responsivegrid
The itemPath
maps to the responsivegrid
node defined in the Remote SPA Page
AEM Template and is automatically created on new AEM Pages created from the Remote SPA Page
AEM Template.
Update App.js
to add the <AEMResponsiveGrid...>
component.
...
import AEMResponsiveGrid from './components/aem/AEMResponsiveGrid';
...
function Home() {
return (
<div className="Home">
<AEMResponsiveGrid
pagePath='/content/wknd-app/us/en/home'
itemPath='root/responsivegrid'/>
<AEMTitle
pagePath='/content/wknd-app/us/en/home'
itemPath='title'/>
<Adventures />
</div>
);
}
The Apps.js
file should look like:
To get the full effect of the flexible authoring experience containers provide in SPA Editor. We’ve already create an editable Title component, but let’s make a few more that allow authors to use Text and Image AEM WCM Core Components in the newly added container component.
Open the SPA project in your IDE
Create a React component at src/components/aem/AEMText.js
Add the following code to AEMText.js
import { withMappable, MapTo } from '@adobe/aem-react-editable-components';
import { TextV2, TextV2IsEmptyFn } from "@adobe/aem-core-components-react-base";
const RESOURCE_TYPE = "wknd-app/components/text";
const EditConfig = {
emptyLabel: "Text",
isEmpty: TextV2IsEmptyFn,
resourceType: RESOURCE_TYPE
};
MapTo(RESOURCE_TYPE)(TextV2, EditConfig);
const AEMText = withMappable(TextV2, EditConfig);
export default AEMText;
The AEMText.js
file should look like:
Open the SPA project in your IDE
Create a React component at src/components/aem/AEMImage.js
Add the following code to AEMImage.js
import { withMappable, MapTo } from '@adobe/aem-react-editable-components';
import { ImageV2, ImageV2IsEmptyFn } from "@adobe/aem-core-components-react-base";
const RESOURCE_TYPE = "wknd-app/components/image";
const EditConfig = {
emptyLabel: "Image",
isEmpty: ImageV2IsEmptyFn,
resourceType: RESOURCE_TYPE
};
MapTo(RESOURCE_TYPE)(ImageV2, EditConfig);
const AEMImage = withMappable(ImageV2, EditConfig);
export default AEMImage;
Create an SCSS file src/components/aem/AEMImage.scss
that provides custom styles for the AEMImage.scss
. These styles target the AEM React Core Component’s BEM-notation CSS classes.
Add the following SCSS to AEMImage.scss
.cmp-image__image {
margin: 1rem 0;
width: 100%;
border: 0;
}
Import AEMImage.scss
in AEMImage.js
...
import './AEMImage.scss';
...
The AEMImage.js
and AEMImage.scss
should look like:
The newly created AEMText
and AEMImage
SPA components are referenced in the SPA, and are dynamically instantiated based on the JSON returned by AEM. To ensure that these components are available to the SPA, create import statements for them in App.js
Open the SPA project in your IDE
Open the file src/App.js
Add import statements for AEMText
and AEMImage
...
import AEMText from './components/aem/AEMText';
import AEMImage from './components/aem/AEMImage';
...
The result should look like:
If these imports are not added, the AEMText
and AEMImage
code will not be invoked by SPA, and thus, the components are not registered against the provided resource types.
AEM container components use policies to dictate their allowed components. This is a critical configuration when using SPA Editor, since only AEM WCM Core Components that have mapped SPA component counterparts are render-able by the SPA. Ensure only the components which we’ve provided SPA implementations for are allowed:
AEMTitle
mapped to wknd-app/components/title
AEMText
mapped to wknd-app/components/text
AEMImage
mapped to wknd-app/components/image
To configure the Remote SPA Page template’s reponsivegrid container:
Log in to AEM Author
Navigate to Tools > General > Templates > WKND App
Edit Report SPA Page
Select Structure in the mode switcher in the top right
Tap to select the Layout Container
Tap the Policy icon in the popup bar
On the right, under the Allowed Components tab, expand WKND APP - CONTENT
Ensure only following are selected:
Tap Done
With the SPA updated to embed the <AEMResponsiveGrid...>
, wrappers for three AEM React Core components (AEMTitle
, AEMText
, and AEMImage
), and AEM is updated with a matching Template policy, we can start authoring content in the container component.
Log in to AEM Author
Navigate to Sites > WKND App
Tap Home and select Edit from the top action bar
Select Edit from the mode-selector in the top-right of the Page Editor
Locate the Layout Container editable area beneath the Title
Open the Page Editor’s side bar, and select the Components view
Drag the following components into the Layout Container
Drag the components to reorder them to the following order:
Author the Title component
Author the Image component
Author the Text component
Your components are now authored, but stack vertically.
Use AEM’s Layout Mode to allow us to adjust the size and layout of the components.
Switch to Layout Mode using the mode-selector in the top-right
Resize the Image and Text components, such that they are side by side
Preview your changes in AEM Page Editor
Refresh the WKND App running locally on http://localhost:3000 to see the authored changes!
You’ve added a container component that allows for editable components to be added by authors to the WKND App! You now know how to:
The next step will be using this same technique to add an editable component to an Adventure Details route in the SPA.