---
title: Creating a Custom Component in AEM as a Front-End Developer
description: Learn how to create custom components in Adobe Experience Manager (AEM) for interactive web applications with our step-by-step guidance for developers.
publish date: 2024-06-11
author: Francisco Cornejo
image: https://www-qa.oshyn.com/-/media/Oshyn/Insights/Blog/2024-06-11-AEM-custom-component-as-a-FE-Dev/blog_hero_aem-custom-component.jpg?rev=463bddc3bbd744b6b4f5f0dc402b1ed7
url: http://www-qa.oshyn.com/blog/2024/06/aem-custom-component
---
# Creating a Custom Component in AEM as a Front-End Developer

![custom computer code](https://www-qa.oshyn.com/-/media/Oshyn/Insights/Blog/2024-06-11-AEM-custom-component-as-a-FE-Dev/blog_hero_aem-custom-component.jpg?rev=463bddc3bbd744b6b4f5f0dc402b1ed7&hash=5C2FCDC4DFD693E902B6283544351B02)

Adobe Experience Manager (AEM) offers several out-of-the-box components that help developers to create dynamic and interactive web applications. However, there are times when front-end developers need to build customized components instead. In this blog we’ll provide some guidance on how to create these custom components.

## Prerequisites

- Running AEM Instance: Make sure your AEM instance is up and running. If you encounter issues, consider referencing a troubleshooting blog.
- Existing Project: A project within AEM where you plan to add your component.

## Steps:

1. Utilize CRXDE Lite: Navigate to http://localhost:4502/crx/de/index.jsp (CRXDE Lite interface).
2. Find Your Project's Component Folder: Locate the appropriate components folder within your project hierarchy.
3. Initiate Component Creation: Right-click the components folder and select "Create Component".
4. Component Dialog: Complete the required fields (note: use lowercase for the label). Click "Next".
5. HTML Markup: Rename the .jsp file to .html to utilize HTL templating.
6. Create the Dialog:
  - Right-click on your new component. Choose "Create Node".
  - Title the dialog popup "cq:dialog" and type “nt:unstructured”.
7. Dialog conf
  - jcr:primaryType: nt:unstructured
  - jcr:title: Properties
  - sling:resourceType: cq/gui/components/authoring/dialog
8. Create a new node from the dialog path:
  - Create a new node from the dialog path and name it content
  - Configure the content item with:
    - jcr:primaryType: nt:unstructured
    - sling:resourceType: granite/ui/components/coral/foundation/fixedcolumns
9. Create a new node from the content path called "items" with type "nt:unstructured
  - Config:
    - jcr:primaryType: nt:unstructured
10. Create a new node from the “items“ path called “column“
  - Config:
    - jcr:primaryType: nt:unstructured
    - sling:resourceType: granite/ui/components/coral/foundation/container
11. Create a new node from the “column“ path and name it “items“
  - Config:
    - jcr:primaryType: nt:unstructured
12. Create a new node from the “item“ path and give it a name. example: “text“
  - Config ( this is going to change depending on the type of field you need ):
    - jcr:primaryType: nt:unstructured
    - sling:resourceType: granite/ui/components/coral/foundation/fixedcolumns
    - fieldLabel: Text of your label
    - name:’./text' ( this needs to be added this way so that the value is stored in this path )
13. Utilize VS Code and AEM Sync: Install the VSCode AEM Sync extension for seamless code synchronizing. This is the easiest and quickest way to do it. Alternatively, you can spin up the environment again so that AEM accepts the new changes but that may be time consuming.
14. Write Your HTML Code:
  - Include new fields in your HTML. Example:


### aemCustomComponent.sh

```
#!/bin/bash

# Gather input from the user
echo "Enter component name (e.g., my-component): "
read COMPONENT_NAME

echo "Enter component Title (e.g., My Component): "
read COMPONENT_TITLE

echo "Enter component Group (e.g., My Component): "
read COMPONENT_GROUP

echo "Enter desired path within AEM apps structure (e.g., /apps/my-project/components): "
read COMPONENT_PATH

# Create the component directory structure
mkdir -p "$COMPONENT_PATH/$COMPONENT_NAME"
cd "$COMPONENT_PATH/$COMPONENT_NAME"

# Generate essential files with basic content

# .content.xml
echo '<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
    jcr:primaryType="cq:Component"
    jcr:title="'$COMPONENT_TITLE'"
    componentGroup="'$COMPONENT_GROUP'"/>' > .content.xml

# _cq_dialog.xml (A very basic dialog with a text field)
echo '<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
xmlns:cq="http://www.day.com/jcr/cq/1.0"
xmlns:jcr="http://www.jcp.org/jcr/1.0"
xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
    jcr:primaryType="nt:unstructured"
    jcr:title="Properties"

sling:resourceType="cq/gui/components/authoring/dialog">
    <content
        jcr:primaryType="nt:unstructured"

sling:resourceType="granite/ui/components/coral/foundation/fixedcolumns">
        <items jcr:primaryType="nt:unstructured">
            <column
                jcr:primaryType="nt:unstructured"

sling:resourceType="granite/ui/components/coral/foundation/container">
                <items jcr:primaryType="nt:unstructured">
                    <text
                        jcr:primaryType="nt:unstructured"
                        sling:resourceType="granite/ui/components/coral/foundation/form/textfield"
                        fieldLabel="Text"
                        name="./text"/>
                </items>
            </column>
        </items>
    </content>
</jcr:root>' > _cq_dialog.xml

# my-component.html (Simple text output, you'll likely expand this)
echo '<div>${properties.text}</div>' > $COMPONENT_NAME.html

# Create clientlibs
mkdir clientlibs

# Inform the user
echo "AEM component structure created at: $COMPONENT_PATH/$COMPONENT_NAME"
```
