Wednesday 30 August 2017

Integrate AEM with React JS library


React is a Javascript library developed solely for the purpose of UI designing. It was developed in Facebook to facilitate the implementation of reusable, interactive and stateful UI components. Facebook use this library in production. 
It carefully notes down the differences in in-memory cache and use these differences to update the DOM in browser, which is what gives him the boost. This is the Virtual DOM feature.

Why React?

Firstly react is really fast. Another thing is that it is really understandable. Anyone with a basic previous knowledge in programming can easily understand React while Angular and Ember are referred to as ‘Domain specific Language’, implying that it is difficult to learn them. Another cool feature of React is that it can be used to create mobile applications (React Native). And React is a die hard fan of reusability, meaning extensive code reusability is supported (using components ). Another main feature is that he supports server-side rendering, which helps in solving performance and SEO problems.

React vs Angular

React alone is not comparable to Angular. Angular is an entire framework while React is just a library. But with React Router (for routing), Relay, GraphQL (for declaring dependencies) and React Native, it clearly outweighs Angular. 

With React we attain the freedom to choose, which is lacking in Angular. This freedom of choice is a great deal since developers can make decisions on  how and what to use with React. But Angular does not provide this freedom. We are bound to follow some rules and hence developers are limited to choices.

With the release of Angular 2.0, and the news that it is not backward compatible,  React swooped in and stole the hearts and minds of legions of developers with a ‘simple view library’. React has moved on from a simple view ‘library’ to an ‘ecosystem’ and more and more developers are  flowing in. 

React js Reddit popularity stats show that it is  growing at an amazing rate of 40% every month, which is impressive.


  • Java 8 (Oracle JDK with nashorn engine)
  • AEM 6.X

Create maven project

mvn archetype:generate 

Click here to know how to create a maven project.

If we run only mvn clean install -PautoInstallPackage then we may get below error.
The build is failure.
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-gpg-plugin:1.5:sign (sign-artifacts) on project aem-react: Exit code: 1 -> [Help 1]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1]

To avoid this error add -Dgpg.skip=true to the maven command

Creating react component:

1.Start npm watch task

Start the watch task which transpiles, bundles and uploads the javascript files to AEM.
Open console to folder /src/main/ts and run the watch task npm run watch
ERROR in D:\CQ5\Components\aem-react-master\aem-react-master\demo\src\main\ts\typings\globals\react\index.d.ts
(159,11): error TS2559: Type 'Component<P, S>' has no properties in common with type 'ComponentLifecycle<P, S>'.

ERROR in ./componentRegistry.tsx
(14,19): error TS2345: Argument of type 'typeof Embedded' is not assignable to parameter of type 'typeof Component'.
  Types of parameters 'props' and 'props' are incompatible.
    Type 'P' is not assignable to type 'ResourceProps'.

To avoid this error check the typescript version using tsc -v command.
Downgrade version to 2.3.2

npm install -g typescript@2.3.2

Check package.json for AEM port number.

"config": {
    "crx": "http://admin:admin@localhost:4502/crx/repository/crx.default"

or you can directly set it using below command

npm config set demo:crx http://admin:admin@localhost:4502/crx/repository/crx.default

2. create file

Create a file MyComponent.tsx under /ui.apps/src/main/ts/.
import {ResourceComponent} from "aem-react-js/component/ResourceComponent";
import * as React from "react";
import Text from "./text/text";

export default class MyComponent extends ResourceComponent<any, any, any> {
    public renderBody(): React.ReactElement<any> {

        let label: string = this.getResource().label;
        return (
                <span>Hello {label}</span>
                <Text path="text"/>

3. Register component

The component needs to be associated with a resourceType ${appsFolderName}/components/my-component. Open /ui.apps/src/main/ts/componentRegistry.tsx and add two lines
 // add this line at the top
 import MyComponent from "./MyComponent";
 // add this line after componentRegistry is instantiated

4. Create component configuration

Create the component configuration in the appropriate folder /apps/${appsFolderName}/components/my-component. The template is an empty file called my-component.jsx. The edit dialog should provide a textfield for the property ./label.
  • /apps/${appsFolderName}/components/my-component
    • .content.xml
    • my-component.jsx
    • dialog.xml

5. Synchronize source code to crx

The component configuration must be uploaded to crx. This can be done via maven install -PautoInstallPackage -Dgpg.skip=true . The watch task has already uploaded the javascript file. You can use aemsync tool to push code changes to crx.

6. Open browser

find the new react component in the sidekick.