Skip to content

Latest commit

 

History

History

components

Components

Page

Render an AEM page and its content and enable authoring on AEM. All child components still need to be mapped to their AEM resourcetypes using MapTo or the components prop. All mapped components also need to be updated to use the newly introduced wrapper EditableComponent.

Default SPA

For default SPA on AEM, the component can be used as-is OOTB.

Migration to v2

export default MapTo('wknd-spa-react/components/page')(
  withComponentMappingContext(withRoute(AppPage))
);

can be simplified and now instead be -

export default MapTo('wknd-spa-react/components/page')(
  withRoute(AppPage)
);
export default withModel(App);

can be removed and can be used simply as -

export default App;

Remote SPA

When using the component directly within the app for remote SPA, an additional prop pagePath can be used to pass the path of the corresponding page on AEM.

<Page 
  pagePath='/content/wknd-app/us/en/home' />

Here, the Page component will render content on the AEM page at us/en/home within the project wknd-app

ResponsiveGrid

Render an AEM Layout Container and its content and enable authoring on AEM. Child components to be rendered within the container should be mapped to their AEM resourcetypes using MapTo.

The OOTB ResponsiveGrid component maps to the resourceType wcm/foundation/components/responsivegrid by default.

Default SPA

For default SPA on AEM, the component can be used as-is OOTB.

Remote SPA

When using the component directly within the app for remote SPA, two additional props pagePath and itemPath can be used to pass the path of the corresponding content on AEM.

<ResponsiveGrid 
  pagePath='/content/wknd-app/us/en/home'
  itemPath='root/responsivegrid' />

Here,the ResponsiveGrid component will render content of the layout container /content/wknd-app/us/en/home/jcr:content/root/responsivegrid where /content/wknd-app/us/en/home is the page on AEM and root/responsivegrid the path to the item to be rendered within the page.

Virtual Container

The ResponsiveGrid component can still be used if content does not exist yet on AEM at the defined path. This will simply add an overlay on AEM for the author when opened for editing in AEM. More details are available in the docs.

Custom class for ResponsiveGrid

If a custom class name needs to be added to the OOTB ResponsiveGrid component, this can be done by passing in the class names as a string via the prop customClassName

<ResponsiveGrid 
  pagePath='/content/wknd-app/us/en/home'
  itemPath='root/responsivegrid'
  customClassName='newUserStyleClass' />

Container

For all container components other than ResponsiveGrid, you can either use the Container component as-is or use the helper method getChildComponents() and then render them according to the markup requirements.

Default SPA

Lets say you want to use the WCM Core Container component, and based on user's selection it can either be a ResponsiveGrid or a normal Container.

Here is a sample snippet of how it can be acheived.

const MyContainerEditConfig = {
  emptyLabel: 'Container',
  isEmpty: function(props){
    return !props.cqItemsOrder || !props.cqItemsOrder.length ===0
  }
}

const MyContainer = (props) => 
{
  const MyComponent = (props.layout!=="SIMPLE")?ResponsiveGrid:Container;
  return <MyComponent {...props} />;
}

MapTo('/wknd/components/content/container')(MyContainer, MyContainerEditConfig);

Now lets say you want to render a custom markup for your container, example - a component like Tabs which is also a container, then the sample snippet above can be refactored.

const MyTabsEditConfig = {
  emptyLabel: 'Tabs',
  isEmpty: function(props){
    return !props.cqItemsOrder || !props.cqItemsOrder.length ===0
  }
}

const MyTabs = (props) => 
{
  const tabItemsInOrder = Container.getChildComponents(props);

  const tabItemsJsx = tabItemsInOrder.map((tabItemJsx) =><div className="tab-item">{tabItemJsx}</div>);

  return <div className="tabs">{tabItemsJsx}</div>;
}

MapTo('/wknd/components/content/tabs')(MyTabs, MyTabsEditConfig);

Migration to v2

Before SPA 2.0, Container component is a class based component an it required the consumers to instantiate the class or use class based inheritance to ontain the child components e.g. this.childComponents in your custom implementation loaded all the child components as an array. Now this needs to be replaced with the helper method as shown in sample snippet above.

Remote SPA

<Container 
  pagePath='/content/wknd-app/us/en/home'
  itemPath='root/responsivegrid/container' />

For a custom container, you shall be able to adopt same guidelines followed for normal SPA.

Additional Features

Prefetched Model

If the model for rendering the component has already been fetched (for eg: in SSR), this can be passed into the component via a prop, so that the component doesn't need to fetch it again on the client side.

const App = ({ model }) => (
  <ResponsiveGrid 
    pagePath='/content/wknd-app/us/en/home'
    itemPath='root/responsivegrid'
    model={model} />
);

Remove AEM grid styling

AEM layouting styles are applied by default when using the ResponsiveGrid and Page components. If you would prefer to use your own custom layouting over the AEM authored layouts, an additional prop removeDefaultStyles can be passed into the components.

<ResponsiveGrid 
  pagePath='/content/wknd-app/us/en/home'
  itemPath='root/responsivegrid'
  removeDefaultStyles={true} />

This will remove all styles specific to the AEM grid system and corresponsing DOM wrappers.

Component Mapping

Mapping child components to a container component can now be done via a prop instead of having to do MapTo on initial load.

If the container components has 2 child components, Text and Image of resource type wknd/text and wknd/image respectively, these can now be mapped to a grid component as below -

<ResponsiveGrid 
  pagePath='/content/wknd-app/us/en/home'
  itemPath='root/responsivegrid'
  components={{
    "wknd/text": Text,
    "wknd/image": Image
  }} />

Mapping of the resource type to the corresponding component will then be handled internally by the SPA SDK.

Lazy Loading

Child components can be lazy loaded to ensure that they are dynamically imported only when needed, thus reducing the amount of code on initial load.

Prerequisites

Using with RemotePage component

To ensure the lazy loaded chunks are imported from the appropriate origin and not the AEM instance when the app is rendered for authoring in the AEM editor, update the SPA to explicitly set the public path to the host URL of the SPA.

MapTo

import Text from ./components/Text';
MapTo('wknd/text')(Text);

can be updated to lazy load the Text component on usage as below -

MapTo('wknd/text')(React.lazy(() => import('./components/Text')));

components Prop

<ResponsiveGrid 
  ...
  components={{
    "wknd/text": Text
  }} />

can be updated to lazy load the child components on usage as below -

<ResponsiveGrid 
  ...
  components={{
    "wknd/text": React.lazy(() => import('./components/Text'))
  }} />