React is the most favorite programming language amongst front-end developers ever since its release in 2015. Adobe Experience Manager (AEM), one of the sought-after Content Management Solutions (CMS), is preferred by most companies across the globe. Imagine the kind of impact it is going to make when both are combined; they will surely bring incredible changes in websites and mobile applications.
Not many know that installing AEM on local and integrating React for the front- end is pretty simple.
Now even AEM as a cloud service has react as inbuilt program into its archetype as part of Adobe’s best practices known to its Headless CMS architecture.
We have come up with a comprehensive step-by-step guide to help you out while working on AEM 6.5 and React integration. Take a look:
What will the Article Cover?
- Setup
- AEM and React
- Maven
- Generate a new project using the AEM Archetype
- Install React with CRA
- Configure the aem-clientlibs generator
- Configure the frontend-maven-plugin
- Integrate the React app via the client library
Introduction
AEM has multiple options for defining headless endpoints and delivering its content as JSON. Building a React JS app in a pure Headless scenario.
JavaScript Object Notation (JSON) is strictly a text-based format used to represent structured data and is based on JavaScript object syntax. Its lightweight format enables to store and transport data. It is possible for a JavaScript program to convert JSON data into native JavaScript objects.
Another interesting fact is, JSON data code can be written in any programming language.
Setup
- Install Java 1.8+ and setup the environment variable Environment Variable with JAVA_HOME/bin
- Install Apache Maven 3.3.39+ and setup the environment variable Environment Variable with MAVEN_HOME/bin
- Install Node.js v10+ and npm v6+. For front end, we need Node.js and npm installed. Node comes with npm so once the installation is done, please check if both tools were added to system by running these commands in command line node -v npm -v Which will print the version.
- Installation of AEM and React steps explained in upcoming blocks
AEM and React
Install AEM 6.5 locally.
Please have the .jar file and license provided; the package should look like this.
Extract the JAR
Either through double-click on JAR or through command line with command
java -jar aem-author-4502.jar
To install AEM, create a new folder, for example C:\Program Files\aem. Then, follow the steps below:
Place the .jar and license files in this directory, and create two new folders: one called author, and one called publish.
Copy the .jar and license file to the author folder. Then, copy the same files to the publish folder, but this time, rename the jar file as follows:
Now you can double-click the author .jar, and this will start up the instance of AEM locally. You should see something like this:
This will open the author instance running on localhost, on port 4502.
Maven
Maven is an exceptional management tool which is based on POM (Project Object Model). It is predominantly used for any Java-based projects build, dependency and documentation.
Add the Adobe public profile to your Maven settings.xml
The overview of this process is also described here, but I will list the steps below.
There are two locations where the Maven settings.xml file has been added:
- in the Maven installation folder, under ${maven.home}/conf/settings.xml
- in your user folder, under ${user.home}/.m2/settings.xml
It’s not mandatory to see both these files, but the first one should be there. If both files are present, their content gets merged, and the user-specific settings are applied.
Let’s add the Adobe public profile to the first file. Under settings, you should see something like this:
<settings xmlns=”http://maven.apache.org/SETTINGS/1.0.0″
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”xsi:schemaLocation=”http://maven.apache.org/SETTINGS/1.0.0https://maven.apache.org/xsd/settings-1.0.0.xsd”><localRepository/><interactiveMode/><offline/><pluginGroups/><servers/><mirrors/><proxies/><profiles/><activeProfiles/></settings>
The Adobe profile should be added under <profiles>:
<profiles>
<!– ====================================================== –>
<!– A D O B E P U B L I C P R O F I L E –>
<!– ====================================================== –>
<profile>
<id>adobe-public</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<releaseRepository-Id>adobe-public-releases</releaseRepository-Id>
<releaseRepository-Name>Adobe Public Releases</releaseRepository-Name>
<releaseRepository-URL>https://repo.adobe.com/nexus/content/groups/public</releaseRepository-URL>
</properties>
<repositories>
<repository>
<id>adobe-public-releases</id>
<name>Adobe Public Repository</name>
<url>https://repo.adobe.com/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>adobe-public-releases</id>
<name>Adobe Public Repository</name>
<url>https://repo.adobe.com/nexus/content/groups/public</url>
<releases>
<enabled>true</enabled>
<updatePolicy>never</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
Then, right under </profiles>, add these lines also:
</profiles>
<activeProfiles>
<activeProfile>adobe-public</activeProfile>
</activeProfiles>
</settings>
Now, check if the setup is working by running this command in the command line:
mvn help:effective-settings
Generate a New Project Using the AEM Archetype
Start the local AEM author environment by double-clicking the aem-author-p4502.jar file. This should be running in the background.
Then, get the AEM project archetype from here. Add it to the same project folder, then open the command line and in that folder, run this command:
mvn -B archetype:generate -DarchetypeGroupId=com.adobe.granite.archetypes -DarchetypeArtifactId=aem-project-archetype -DarchetypeVersion=23 -DaemVersion=6.5.0 -DappTitle=”AemReact” -DappId=”aemreact” -DgroupId=”com.aemreact” -DfrontendModule=”react” -DincludeExamples=n
This will create a new folder called “aemreact” with all the needed tools and dependencies. Also, you should see an ui.frontend folder, which contains your React application and dependencies.
In the parent folder of your project, run this command to deploy your project, as it is for now, to your local AEM instance:
mvn clean install -PautoInstallPackage -Padobe-public
If you now navigate in the browser to http://localhost:4502, you should see the AEM React project:
The problem that I had with this setup was that the React app was not loaded into AEM, so the page was blank. For this reason, I installed create-react-app on top of this implementation, and then used this application instead of the default one.
Install React with CRA
Create-react-App (CRA) is one of the popular tools used to create, build and test a React app. CRA creates front-end build pipeline and enables you to use it with any backend of your choice. It does not address databases or backend logics.
Install React using create-react-app (CRA), by running this command in the aemreact folder, in the terminal:
npx create-react-app react-app
Now move to the react-app folder, and run this command in the terminal:
npm install
npm run start
Your React application should be available at http://localhost:3000 to view it in the browser.
Next step is to build the production build by running this command in the terminal:
npm run build
In VSCode I usually open another terminal, but you can also press ctrl+c for stopping the previous process and then run this command.
Move the React files into an AEM client library
We want our React app to run inside AEM, not as a separate project, so we need to move these files into an AEM client library and deploy it as part of the ui.apps module.
UI.app is a modern browser-based no-code editor. Build anything, ship anywhere.
We will use two tools for this:
- aem-clientlib-generator — used to transform compiled CSS and JS files into an AEM client library
- frontend-maven-plugin — used to trigger NPM commands via a Maven build.
Configure the aem-clientlibs generator
In your aemreact/react-app folder, install the aem-clientlibs-generator node plugin by running this command in the terminal:
npm install aem-clientlib-generator –save-dev// You should see the dev dependency added to your package.json file.
Next, create a new file in the react-app folder, and name it clientlib.config.js. In this file, add the following code:
module.exports = {// default working directory (can be changed per ‘cwd’ in every asset option)context: __dirname,// path to the clientlib root folder (output)clientLibRoot: “./../ui.apps/src/main/content/jcr_root/apps/aemreact/clientlibs”,libs: {name: “react-app”,allowProxy: true,categories: [“aemreact.react”],serializationFormat: “xml”,jsProcessor: [“min:gcc”],assets: {js: [“build/static/**/*.js”],css: [“build/static/**/*.css”]}}};
Next, add the clientlib directive as part of the npm run build script by updating react-app/package.json file as follows:
{“name”: “react-app”,
“version”: “0.1.0”,
“private”: true,
“dependencies”: {
“@testing-library/jest-dom”: “^4.2.4”,
“@testing-library/react”: “^9.5.0”,
“@testing-library/user-event”: “^7.2.1”,
“react”: “^16.13.1”,
“react-dom”: “^16.13.1”,
“react-scripts”: “3.4.1”
},
“scripts”: {
“start”: “react-scripts start”,
“build”: “react-scripts build && clientlib –verbose”,
“test”: “react-scripts test”,
“eject”: “react-scripts eject”
},
“eslintConfig”: {
“extends”: “react-app”
},
“browserslist”: {
“production”: [
“>0.2%”,
“not dead”,
“not op_mini all”
],
“development”: [
“last 1 chrome version”,
“last 1 firefox version”,
“last 1 safari version”
]
},
“devDependencies”: {
“aem-clientlib-generator”: “^1.7.1”
}
}
To test if it’s all good until now, run this command in the react-app folder, in the terminal:
npm run build
You should now see in ui/apps/src/main/content/jcr_root/apps/react-app/clientlibs/ a folder named react-app, which contains css and js files generated from the react app.
Configure the frontend-maven-plugin
The next step is to turn the react-app project into a Maven module. You can do this by following the steps below:
- Open the parent xml file found in the aemreact/ folder. Add the following code:
<?xml version=”1.0″ encoding=”UTF-8″?><!–| Copyright 2015 Adobe Systems Incorporated|| Licensed under the Apache License, Version 2.0 (the “License”);| you may not use this file except in compliance with the License.| You may obtain a copy of the License at|| http://www.apache.org/licenses/LICENSE-2.0|| Unless required by applicable law or agreed to in writing, software| distributed under the License is distributed on an “AS IS” BASIS,| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.| See the License for the specific language governing permissions and| limitations under the License.–><project xmlns=”http://maven.apache.org/POM/4.0.0″xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd”><modelVersion>4.0.0</modelVersion><groupId>com.aemreact</groupId><artifactId>aemreact</artifactId><packaging>pom</packaging><version>1.0-SNAPSHOT</version><description>AemReact</description><modules><module>all</module><module>core</module><module>react-app</module><!–<module>ui.frontend</module>–><module>ui.apps</module><module>ui.apps.structure</module><module>ui.content</module><module>it.tests</module><module>it.launcher</module><module>dispatcher</module></modules><properties><aem.host>localhost</aem.host><aem.port>4502</aem.port><aem.publish.host>localhost</aem.publish.host><aem.publish.port>4503</aem.publish.port><sling.user>admin</sling.user><sling.password>admin</sling.password><vault.user>admin</vault.user><vault.password>admin</vault.password><!– Update: Used by frontend-maven-plugin –><frontend-maven-plugin.version>1.6</frontend-maven-plugin.version><node.version>v8.16.1</node.version><npm.version>6.4.1</npm.version><!– end update –><core.wcm.components.version>2.8.0</core.wcm.components.version><bnd.version>5.0.0</bnd.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spa.project.core.version>1.0.6</spa.project.core.version></properties><build><plugins><!– Maven Release Plugin –><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-release-plugin</artifactId><version>2.5.3</version><configuration><scmCommentPrefix>[maven-scm] :</scmCommentPrefix><preparationGoals>clean install</preparationGoals><goals>install</goals><releaseProfiles>release</releaseProfiles></configuration></plugin><!– Maven Source Plugin –><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-source-plugin</artifactId><version>3.0.1</version><inherited>true</inherited></plugin><!– Maven Enforcer Plugin –><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-enforcer-plugin</artifactId><executions><execution><id>enforce-maven</id><goals><goal>enforce</goal></goals><configuration><rules><requireMavenVersion><version>[3.3.9,)</version></requireMavenVersion><requireJavaVersion><message>Project must be compiledwith Java 8 or higher</message><version>1.8.0</version></requireJavaVersion></rules></configuration></execution></executions></plugin><!– Maven Compiler Plugin –><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins><pluginManagement><plugins><plugin><groupId>com.github.eirslett</groupId><artifactId>frontend-maven-plugin</artifactId><version>1.7.6</version><configuration><nodeVersion>v10.13.0</nodeVersion><npmVersion>6.9.0</npmVersion></configuration><executions><execution><id>install node and npm</id><goals><goal>install-node-and-npm</goal></goals></execution><execution><id>npm install</id><goals><goal>npm</goal></goals></execution></executions></plugin><!– Maven Jar Plugin –><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>3.1.2</version></plugin><!– Maven Clean Plugin –><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-clean-plugin</artifactId><version>3.0.0</version></plugin><!– BND Maven Plugin –><plugin><groupId>biz.aQute.bnd</groupId><artifactId>bnd-maven-plugin</artifactId><version>${bnd.version}</version><executions><execution><id>bnd-process</id><goals><goal>bnd-process</goal></goals><configuration><bnd><![CDATA[Bundle-Category: ${componentGroupName}# export all versioned packages except for conditional ones (https://github.com/bndtools/bnd/issues/3721#issuecomment-579026778)-exportcontents: ${removeall;${packages;VERSIONED};${packages;CONDITIONAL}}# reproducible builds (https://github.com/bndtools/bnd/issues/3521)-noextraheaders: true-snapshot: SNAPSHOTBundle-DocURL:-plugin org.apache.sling.caconfig.bndplugin.ConfigurationClassScannerPlugin-plugin org.apache.sling.bnd.models.ModelsScannerPlugin]]></bnd></configuration></execution></executions><dependencies><dependency><groupId>org.apache.sling</groupId><artifactId>org.apache.sling.caconfig.bnd-plugin</artifactId><version>1.0.2</version></dependency><dependency><groupId>org.apache.sling</groupId><artifactId>org.apache.sling.bnd.models</artifactId><version>1.0.0</version></dependency></dependencies></plugin><plugin><groupId>biz.aQute.bnd</groupId><artifactId>bnd-baseline-maven-plugin</artifactId><version>${bnd.version}</version></plugin><!– Maven Resources Plugin –><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><version>3.0.2</version></plugin><!– Maven Compiler Plugin –><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version></plugin><!– Maven Installer Plugin –><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-install-plugin</artifactId><version>2.5.2</version></plugin><!– Maven Surefire Plugin –><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>2.22.1</version><configuration><useSystemClassLoader>false</useSystemClassLoader></configuration></plugin><!– Maven Failsafe Plugin –><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-failsafe-plugin</artifactId><version>2.22.1</version></plugin><!– Maven Deploy Plugin –><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-deploy-plugin</artifactId><version>2.8.2</version></plugin><!– Apache Sling Plugin –><plugin><groupId>org.apache.sling</groupId><artifactId>sling-maven-plugin</artifactId><version>2.4.0</version><configuration><slingUrl>http://${aem.host}:${aem.port}/system/console</slingUrl><deploymentMethod>WebConsole</deploymentMethod></configuration></plugin><!– HTL Maven Plugin –><plugin><groupId>org.apache.sling</groupId><artifactId>htl-maven-plugin</artifactId><version>1.3.4-1.4.0</version><configuration><failOnWarnings>true</failOnWarnings></configuration></plugin><!– Jackrabbit FileVault Package Plugin –><plugin><groupId>org.apache.jackrabbit</groupId><artifactId>filevault-package-maven-plugin</artifactId><version>1.0.3</version><configuration><filterSource>src/main/content/META-INF/vault/filter.xml</filterSource></configuration></plugin><!– Content Package Plugin –><plugin><groupId>com.day.jcr.vault</groupId><artifactId>content-package-maven-plugin</artifactId><version>1.0.2</version><configuration><targetURL>http://${aem.host}:${aem.port}/crx/packmgr/service.jsp</targetURL><failOnError>true</failOnError><userId>${vault.user}</userId><password>${vault.password}</password></configuration></plugin><!– Maven Enforcer Plugin –><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-enforcer-plugin</artifactId><version>1.4.1</version></plugin><!– Maven Dependency Plugin –><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><version>3.0.0</version></plugin><!– Build Helper Maven Plugin –><plugin><groupId>org.codehaus.mojo</groupId><artifactId>build-helper-maven-plugin</artifactId><version>3.0.0</version></plugin><!–This plugin’s configuration is used to store Eclipsem2e settings only. It has no influence on the Maven build itself. –><plugin><groupId>org.eclipse.m2e</groupId><artifactId>lifecycle-mapping</artifactId><version>1.0.0</version><configuration><lifecycleMappingMetadata><pluginExecutions><pluginExecution><pluginExecutionFilter><groupId>org.apache.maven.plugins</groupId><artifactId>maven-enforcer-plugin</artifactId><versionRange>[1.0.0,)</versionRange><goals><goal>enforce</goal></goals></pluginExecutionFilter><action><ignore /></action></pluginExecution><pluginExecution><pluginExecutionFilter><groupId>org.apache.maven.plugins</groupId><artifactId>maven-dependency-plugin</artifactId><versionRange>[2.2,)</versionRange><goals><goal>copy-dependencies</goal><goal>unpack</goal></goals></pluginExecutionFilter><action><ignore /></action></pluginExecution><pluginExecution><pluginExecutionFilter><groupId>org.codehaus.mojo</groupId><artifactId>build-helper-maven-plugin</artifactId><versionRange>[1.5,)</versionRange><goals><goal>reserve-network-port</goal></goals></pluginExecutionFilter><action><ignore /></action></pluginExecution></pluginExecutions></lifecycleMappingMetadata></configuration></plugin></plugins></pluginManagement></build><profiles><!– ====================================================== –><!– A D O B E P U B L I C P R O F I L E –><!– ====================================================== –><profile><id>adobe-public</id><activation><activeByDefault>true</activeByDefault></activation><properties><releaseRepository-Id>adobe-public-releases</releaseRepository-Id><releaseRepository-Name>Adobe Public Releases</releaseRepository-Name><releaseRepository-URL>https://repo.adobe.com/nexus/content/groups/public</releaseRepository-URL></properties><repositories><repository><id>adobe-public-releases</id><name>Adobe Public Repository</name><url>https://repo.adobe.com/nexus/content/groups/public</url><releases><enabled>true</enabled><updatePolicy>never</updatePolicy></releases><snapshots><enabled>false</enabled></snapshots></repository><repository><id>adobe-aem-releases</id><name>Adobe AEM Repository</name><url>https://downloads.experiencecloud.adobe.com/content/maven/public</url><releases><enabled>true</enabled><updatePolicy>never</updatePolicy></releases><snapshots><enabled>false</enabled></snapshots></repository></repositories><pluginRepositories><pluginRepository><id>adobe-public-releases</id><name>Adobe Public Repository</name><url>https://repo.adobe.com/nexus/content/groups/public</url><releases><enabled>true</enabled><updatePolicy>never</updatePolicy></releases><snapshots><enabled>false</enabled></snapshots></pluginRepository></pluginRepositories></profile><!– Development profile: install only the bundle –><profile><id>autoInstallBundle</id><!–To enable this feature for a bundle, the sling-maven-plugin(without configuration) needs to be included:<plugin><groupId>org.apache.sling</groupId><artifactId>sling-maven-plugin</artifactId></plugin>–><activation><activeByDefault>false</activeByDefault></activation><build><pluginManagement><plugins><plugin><groupId>org.apache.sling</groupId><artifactId>sling-maven-plugin</artifactId><executions><execution><id>install-bundle</id><goals><goal>install</goal></goals></execution></executions></plugin></plugins></pluginManagement></build></profile><profile><id>autoInstallPackage</id><activation><activeByDefault>false</activeByDefault></activation><build><pluginManagement><plugins><plugin><groupId>org.apache.jackrabbit</groupId><artifactId>filevault-package-maven-plugin</artifactId><executions><execution><id>create-package</id><goals><goal>package</goal></goals></execution></executions></plugin><plugin><groupId>com.day.jcr.vault</groupId><artifactId>content-package-maven-plugin</artifactId><executions><execution><id>install-package</id><goals><goal>install</goal></goals><configuration><targetURL>http://${aem.host}:${aem.port}/crx/packmgr/service.jsp</targetURL></configuration></execution></executions></plugin></plugins></pluginManagement></build></profile><profile><id>autoInstallPackagePublish</id><activation><activeByDefault>false</activeByDefault></activation><build><pluginManagement><plugins><plugin><groupId>org.apache.jackrabbit</groupId><artifactId>filevault-package-maven-plugin</artifactId><executions><execution><id>create-package</id><goals><goal>package</goal></goals></execution></executions></plugin><plugin><groupId>com.day.jcr.vault</groupId><artifactId>content-package-maven-plugin</artifactId><executions><execution><id>install-package-publish</id><goals><goal>install</goal></goals><configuration><targetURL>http://${aem.publish.host}:${aem.publish.port}/crx/packmgr/service.jsp</targetURL></configuration></execution></executions></plugin></plugins></pluginManagement></build></profile></profiles><!–
===================================================================
=== –><!– D E P E N D E N C I E S –><!–
====================================================================== –><dependencyManagement><dependencies><!– OSGi Dependencies –><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.annotation.versioning</artifactId><version>1.1.0</version><scope>provided</scope></dependency><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.annotation.bundle</artifactId><version>1.0.0</version><scope>provided</scope></dependency><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.service.metatype.annotations</artifactId><version>1.4.0</version><scope>provided</scope></dependency><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.service.component.annotations</artifactId><version>1.4.0</version><scope>provided</scope></dependency><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.service.component</artifactId><version>1.4.0</version><scope>provided</scope></dependency><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.service.cm</artifactId><version>1.6.0</version><scope>provided</scope></dependency><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.service.event</artifactId><version>1.3.1</version><scope>provided</scope></dependency><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.service.log</artifactId><version>1.4.0</version><scope>provided</scope></dependency><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.resource</artifactId><version>1.0.0</version><scope>provided</scope></dependency><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.framework</artifactId><version>1.9.0</version><scope>provided</scope></dependency><dependency><groupId>org.apache.sling</groupId><artifactId>org.apache.sling.servlets.annotations</artifactId><version>1.2.4</version><scope>provided</scope></dependency><!– Logging Dependencies –><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.21</version><scope>provided</scope></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-simple</artifactId><version>1.7.25</version><scope>test</scope></dependency><!– Adobe AEM Dependencies –><dependency><groupId>com.adobe.aem</groupId><artifactId>uber-jar</artifactId><version>6.5.0</version><classifier>apis</classifier><scope>provided</scope></dependency><!– Apache Sling Dependencies –><dependency><groupId>org.apache.sling</groupId><artifactId>org.apache.sling.models.api</artifactId><version>1.3.6</version><scope>provided</scope></dependency><!– Servlet API –><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><dependency><groupId>javax.servlet.jsp</groupId><artifactId>jsp-api</artifactId><version>2.1</version><scope>provided</scope></dependency><dependency><groupId>javax.annotation</groupId><artifactId>javax.annotation-api</artifactId><version>1.3.2</version><scope>provided</scope></dependency><!– JCR –><dependency><groupId>javax.jcr</groupId><artifactId>jcr</artifactId><version>2.0</version><scope>provided</scope></dependency><!– Taglibs –><dependency><groupId>com.day.cq.wcm</groupId><artifactId>cq-wcm-taglib</artifactId><version>5.7.4</version><scope>provided</scope></dependency><dependency><groupId>com.adobe.cq</groupId><artifactId>core.wcm.components.core</artifactId><version>${core.wcm.components.version}</version></dependency><dependency><groupId>com.adobe.cq</groupId><artifactId>core.wcm.components.content</artifactId><type>zip</type><version>${core.wcm.components.version}</version></dependency><dependency><groupId>com.adobe.cq</groupId><artifactId>core.wcm.components.config</artifactId><type>zip</type><version>${core.wcm.components.version}</version></dependency><!– SPA Project Core (includes hierarchy page model) –><dependency><groupId>com.adobe.aem</groupId><artifactId>spa.project.core.all</artifactId><type>zip</type><version>${spa.project.core.version}</version></dependency><dependency><groupId>com.adobe.aem</groupId><artifactId>spa.project.core.core</artifactId><version>${spa.project.core.version}</version></dependency><!– Testing –><dependency><groupId>org.junit</groupId><artifactId>junit-bom</artifactId><version>5.4.1</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.mockito</groupId><artifactId>mockito-core</artifactId><version>2.25.1</version><scope>test</scope></dependency><dependency><groupId>org.mockito</groupId><artifactId>mockito-junit-jupiter</artifactId><version>2.25.1</version><scope>test</scope></dependency><dependency><groupId>junit-addons</groupId><artifactId>junit-addons</artifactId><version>1.4</version><scope>test</scope></dependency><dependency><groupId>io.wcm</groupId><artifactId>io.wcm.testing.aem-mock.junit5</artifactId><version>2.5.2</version><scope>test</scope></dependency><dependency><groupId>uk.org.lidalia</groupId><artifactId>slf4j-test</artifactId><version>1.0.1</version><scope>test</scope></dependency></dependencies></dependencyManagement></project>
Next step is to create a new file named pom.xml in the aemreact/react-app folder. Add the following code:
<?xml version=”1.0″ encoding=”UTF-8″?><project xmlns=”http://maven.apache.org/POM/4.0.0″ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd”><modelVersion>4.0.0</modelVersion><!– ===================================================================
=== –><!– P A R E N T P R O J E C T D E S C R I P T I O N –><!–
====================================================================== –><parent><groupId>com.aemreact</groupId><artifactId>aemreact</artifactId><version>1.0-SNAPSHOT</version><relativePath>../pom.xml</relativePath></parent><!– ===================================================================
=== –><!– P R O J E C T D E S C R I P T I O N –><!–
====================================================================== –><artifactId>aemreact.react.app</artifactId><packaging>pom</packaging><name>WKND Events – React App</name><description>UI React application code for WKND Events</description><!– ===================================================================
=== –><!– B U I L D D E F I N I T I O N –><!–
====================================================================== –><build><plugins><plugin><groupId>com.github.eirslett</groupId><artifactId>frontend-maven-plugin</artifactId><version>${frontend-maven-plugin.version}</version><executions><execution><id>install node and npm</id><goals><goal>install-node-and-npm</goal></goals><configuration><nodeVersion>${node.version}</nodeVersion><npmVersion>${npm.version}</npmVersion></configuration></execution><execution><id>npm install</id><goals><goal>npm</goal></goals><!– Optional configuration which provides for running any npm command –><configuration><arguments>install</arguments></configuration></execution><execution><id>npm run build</id><goals><goal>npm</goal></goals><configuration><arguments>run build</arguments></configuration></execution></executions></plugin></plugins></build></project>
Within the react-app folder run the following Maven command to trigger a front end build:
mvn clean install
Then, move to the parent folder aemreact and in the terminal, run this command to build the entire project and deploy it to AEM:
mvn -PautoInstallPackage -Padobe-public clean install
If you now check the local AEM environment, and navigate to the CRXDE-Lite, you should see the project deployed under /apps/aemreact/clientlibs/react-app.
Integrate the React app via the client library
In the IDE, open up the file customheaderlibs.html which is found under
\aemreact\ui.apps\src\main\content\jcr_root\apps\aemreact\components\page.
Add the following code:
<!–/*Custom Headerlibs for React Site*/–><meta name=”viewport” content=”width=device-width, initial-scale=1″><meta property=”cq:datatype” data-sly-test=”${wcmmode.edit || wcmmode.preview}” content=”JSON”/><meta property=”cq:wcmmode” data-sly-test=”${wcmmode.edit}” content=”edit”/><meta property=”cq:wcmmode” data-sly-test=”${wcmmode.preview}” content=”preview”/><meta property=”cq:pagemodel_root_url”data-sly-use.page=”com.adobe.aem.spa.project.core.models.Page”content=”${page.rootUrl}”/><sly data-sly-use.clientlib=”/libs/granite/sightly/templates/clientlib.html”><sly data-sly-call=”${clientlib.css @ categories=’aemreact.react’}”/>
In the same folder, you should see a customfooterlibs.html file. Replace the existing code with the following:
<!–/*Custom footer React libs*/–><sly data-sly-use.clientLib=”${‘/libs/granite/sightly/templates/clientlib.html’}”></sly><sly data-sly-test=”${wcmmode.edit || wcmmode.preview}”data-sly-call=”${clientLib.js @ categories=’cq.authoring.pagemodel.messaging’}”></sly><sly data-sly-call=”${clientLib.js @ categories=’aemreact.react’}”></sly>
Then, create a new file in the same folder and name it body.html. Add the following code:
<!–/* – body.html – includes div that will be targeted by SPA */–><div id=”root”></div>
To deploy these changes to AEM, we need to run again this command in the project root folder (aemreact):
mvn -PautoInstallPackage -Padobe-public clean install
Navigate to your local AEM instance and you should see your new React application.
Conclusion
We are not comparing React with any other frameworks. Each one comes with its own set of pros and cons; it all depends on your objectives.
But the key attributes like ease-of-use, ease-of-learning, reusable components, great developer-friendly tools, fuss-free programming with JSX, and the entire ecosystem sets React framework apart from other languages.
Author Bio
Chiran Kumar is our Associate Director with an impressive record in Application design and Architecture. For over 11.5 years. He has been at the helm of various digital experience and e-commerce projects for leading software organizations.
Chiran has completed his post-graduation in Computer Applications from Al Ameen College, Bangalore. Apart from work…. Chiran loves to nurture his passion for bikes and travelling.