---
title: Implementing a Container Component (Column Control) in AEM SPA - React
description: Learn how to create a container component for column control in AEM SPA ensuring authors and designers have a useful site feature at their disposal.
image: https://blog.3sharecorp.com/hubfs/Blog%20Content/2023%20Blog%20Images/columns.jpg
---

[![3SHARE_LOGO_WHITE_2018](https://blog.3sharecorp.com/hs-fs/hubfs/2017%20Website%20Assets/Logos/High%20Res/3SHARE_LOGO_WHITE_2018.png?width=266&height=54&name=3SHARE_LOGO_WHITE_2018.png "3SHARE_LOGO_WHITE_2018")](https://www.3sharecorp.com)

![columns representing column controls](https://blog.3sharecorp.com/hubfs/Blog%20Content/2023%20Blog%20Images/columns.jpg)

# Implementing a Container Component (Column Control) in AEM SPA - React

Ankur Rajput, February 21, 2023

The AEM Responsive Grid is indeed powerful but some designs or business requirements make a column control component necessary. Besides its usefulness, those of us who have been developing or authoring in AEM for a long time have become used to using a column control component to layout page content.

The good news is, you can create your own container components, like column control, in an AEM SPA - React project.

All the code required for this is available in our [BitBucket repository](https://bitbucket.org/3SHARE/column-control-in-aem-spa/src/main/). And, the same pattern can be followed for Angular or any other library/framework implementation.

## Prerequisites

Here are some prerequisites to get the most out of the information I’ll share below:

1. Understanding of container components - cq:isContainer property.
2. Knowing how to create/register Sling models for Container component:  
     1. [Sling Model Exporter](https://experienceleague.adobe.com/docs/experience-manager-learn/foundation/development/understand-sling-model-exporter.html?lang=en)
     2. [Container Exporter API](https://developer.adobe.com/experience-manager/reference-materials/6-5/javadoc/com/adobe/cq/export/json/ContainerExporter.html). Examples - [Page](https://github.com/adobe/aem-core-wcm-components/blob/main/bundles/core/src/main/java/com/adobe/cq/wcm/core/components/internal/models/v1/PageImpl.java), [Accordion](https://github.com/adobe/aem-core-wcm-components/blob/main/bundles/core/src/main/java/com/adobe/cq/wcm/core/components/internal/models/v1/AccordionImpl.java), [Tabs](https://github.com/adobe/aem-core-wcm-components/blob/main/bundles/core/src/main/java/com/adobe/cq/wcm/core/components/internal/models/v1/TabsImpl.java), [Carousel](https://github.com/adobe/aem-core-wcm-components/blob/main/bundles/core/src/main/java/com/adobe/cq/wcm/core/components/internal/models/v1/CarouselImpl.java)
3. Knowing how to create basic AEM SPA components and how to do the mapping between React and AEM components.

Note: This was tested on AEM 6.5.12 and AEMaaCS using the latest archetype 39

### Column Control component background

The Column Control is a type of container component that allows content authors to horizontally divide the page’s content area into multiple columns. Each column can be populated with any number of allowed components they place in each column individually.

There are various ways to implement the configuration logic for a Column Control component but for the sake of simplicity and robustness, I have used a fixed list of options from which an author can select their required style/configuration. This can easily be changed to a configurable dynamic list using a datasource. When developing this for your project, it is a good idea to define a list of options based on business requirements.

The authoring dialog for our column control component looks like the below with the aforementioned options available:

![AEM-column-control-dialog](https://blog.3sharecorp.com/hs-fs/hubfs/Blog%20Content/2023%20Blog%20Images/AEM-column-control-dialog.png?width=904&height=471&name=AEM-column-control-dialog.png)

For the styling and implementation logic, we have used [styled-components](https://styled-components.com/) and TypeScript but anything else can be used as well. That is all up to the front-end implementation of the project. The main focus of this article is on how container components work in AEM SPA implementation.

### Implementation

#### Sling Model

I have extended the [aem-core-wcm-component container](https://experienceleague.adobe.com/docs/experience-manager-core-components/using/wcm-components/container.html?lang=en) and used the [Sling delegation pattern](https://github.com/adobe/aem-core-wcm-components/wiki/Delegation-Pattern-for-Sling-Models) to reuse the existing core component logic in our column control component’s sling model.

The exact code line is [here](https://bitbucket.org/3share-lab/column-control-in-aem-spa/src/main/core/src/main/java/com/example/core/models/impl/ColumnControlModelImpl.java#lines-33).

![AEM Column Control Sling Code](https://blog.3sharecorp.com/hs-fs/hubfs/Blog%20Content/2023%20Blog%20Images/AEM%20Column%20Control%20Sling%20Code.png?width=2788&height=1238&name=AEM%20Column%20Control%20Sling%20Code.png)

- As expected we have to follow all other container component practices like implementing the ContainerExporter API and adding ComponentExporter and ContainerExporter in the adapters property of the @Model annotation
- Exported JSON of our column control component (http://localhost:4502/content/aem-spa-container-component/us/en/home/jcr:content/root/responsivegrid/columncontrol.model.tidy.json) 

![AEM Column Control JSON](https://blog.3sharecorp.com/hs-fs/hubfs/Blog%20Content/2023%20Blog%20Images/AEM%20Column%20Control%20JSON.png?width=553&height=781&name=AEM%20Column%20Control%20JSON.png)

 

#### AEM Component Structure

The [structure](https://bitbucket.org/3share-lab/column-control-in-aem-spa/src/main/ui.apps/src/main/content/jcr_root/apps/aem-spa-container-component/components/columncontrol/) is similar to any other AEM component with the below additions:

- “cq:isContainer” property is set to true since this is a container
- “sling:resourceSuperType” is set to the project’s container component/core container component.
- “cq:template” has the node structure for the maximum number of allowed columns (i.e. Layout Containers). In our case, it is 6. The template stubbing is done so that all the required responsive grid nodes are available as soon as the component is added to the page/template, preventing editor issues.

#### React Component structure

- All logic is in the [index.tsx](https://bitbucket.org/3share-lab/column-control-in-aem-spa/src/main/ui.frontend/src/components/ColumnControl/index.tsx).
- The “ColumnControlProps” interface defines the properties structure of our column control component.
- The “ColumnControlConfig” object defines the edit configurations.
- The “ColumnLayoutToNumOfColumnsMap” object defines the mapping between the authoring dialog options and the number of columns.
- “ColumnControl” is the react component representing our column control component. 
    - This will take care of the mapping and initialization of the child components of our component. Like [this.childComponents](https://bitbucket.org/3share-lab/column-control-in-aem-spa/src/main/ui.frontend/src/components/ColumnControl/index.tsx#lines-55) will give all the children of our component that can further be used in our rendering logic.
    - The most important part of creating a container component in the AEM React SPA is **extending the “Container” abstract component** from “@adobe/aem-react-editable-components” module.
    - All other methods like “configuredColumns”, “renderFirstNColumns” are normal JS methods as per the rendering logic of our component.

#### Final Result

In Edit mode:

![AEM Column Control Edit Mode](https://blog.3sharecorp.com/hs-fs/hubfs/Blog%20Content/2023%20Blog%20Images/AEM%20Column%20Control%20Edit%20Mode.png?width=3562&height=1802&name=AEM%20Column%20Control%20Edit%20Mode.png)

In Publish mode (Desktop):

![AEM Column Control Desktop Publish](https://blog.3sharecorp.com/hs-fs/hubfs/Blog%20Content/2023%20Blog%20Images/AEM%20Column%20Control%20Desktop%20Publish.png?width=3562&height=1802&name=AEM%20Column%20Control%20Desktop%20Publish.png)

In Publish mode (Mobile emulator):

![AEM Column Control Mobile Publish](https://blog.3sharecorp.com/hs-fs/hubfs/Blog%20Content/2023%20Blog%20Images/AEM%20Column%20Control%20Mobile%20Publish.png?width=3562&height=1802&name=AEM%20Column%20Control%20Mobile%20Publish.png)

By creating this type of container component, you’ll empower authors to layout content in a more flexible way. The Column Control will become one of the more versatile and handy components at the authors’ disposal.

If you have a challenging AEM Sites use case or any other Adobe Experience Cloud or AWS questions, [get in touch](https://www.3sharecorp.com/contact). The 3|SHARE team would love to help!

Topics: [Adobe Experience Manager](https://blog.3sharecorp.com/topic/adobe-experience-manager), [Development](https://blog.3sharecorp.com/topic/development), [AEM](https://blog.3sharecorp.com/topic/aem), [Adobe](https://blog.3sharecorp.com/topic/adobe)

- [Share on Facebook](https://www.facebook.com/sharer/sharer.php?u=https://blog.3sharecorp.com/implementing-a-container-component-column-control-in-aem-spa-react&display=popup&ref=plugin)
- [Share on Twitter](https://www.twitter.com/home?status=Implementing%20a%20Container%20Component%20(Column%20Control)%20in%20AEM%20SPA%20-%20React%20-%20https://blog.3sharecorp.com/implementing-a-container-component-column-control-in-aem-spa-react)
- [Share on LinkedIn](https://www.linkedin.com/shareArticle?mini=true&url=https://blog.3sharecorp.com/implementing-a-container-component-column-control-in-aem-spa-react&title=Implementing%20a%20Container%20Component%20(Column%20Control)%20in%20AEM%20SPA%20-%20React&summary=&source=)

### [Ankur Rajput](https://blog.3sharecorp.com/author/ankur-rajput)

Ankur Rajput is a Senior AEM Developer at 3|SHARE. He has completed 7 AEM Sites certifications including Developer, Lead Developer and Architect. What he enjoys about working at 3|SHARE is learning, growing, and working on the latest Web technologies with a diverse, global team. When he isn't working, Ankur loves reading and listening to Hindi poetry plus playing chess and badminton.

[LinkedIn](https://www.linkedin.com/in/rajputankur023/)

### Popular Posts

### Posts by Topic

- [Adobe Experience Manager (48)](https://blog.3sharecorp.com/topic/adobe-experience-manager)
- [AEM (33)](https://blog.3sharecorp.com/topic/aem)
- [Adobe (20)](https://blog.3sharecorp.com/topic/adobe)
- [Development (19)](https://blog.3sharecorp.com/topic/development)
- [Digital Marketing (19)](https://blog.3sharecorp.com/topic/digital-marketing)
- [Tech (15)](https://blog.3sharecorp.com/topic/tech)
- [Web Content Management System (13)](https://blog.3sharecorp.com/topic/web-content-management-system)
- [3|SHARE Insider (12)](https://blog.3sharecorp.com/topic/3share-insider)
- [Developer Think Tank (12)](https://blog.3sharecorp.com/topic/developer-think-tank)
- [Digital Asset Management (DAM) (10)](https://blog.3sharecorp.com/topic/digital-asset-management-dam)
- [Professional IT Consulting Services (10)](https://blog.3sharecorp.com/topic/professional-it-consulting-services)
- [Adobe Solutions Partner (8)](https://blog.3sharecorp.com/topic/adobe-solutions-partner)
- [Creative Process (7)](https://blog.3sharecorp.com/topic/creative-process)
- [CMS (6)](https://blog.3sharecorp.com/topic/cms)
- [Content Management System (6)](https://blog.3sharecorp.com/topic/content-management-system)
- [Upgrade (6)](https://blog.3sharecorp.com/topic/upgrade)
- [Content Supply Chain (5)](https://blog.3sharecorp.com/topic/content-supply-chain)
- [Culture (5)](https://blog.3sharecorp.com/topic/culture)
- [Customer Experience (5)](https://blog.3sharecorp.com/topic/customer-experience)
- [Remote Operations Management (ROM) (5)](https://blog.3sharecorp.com/topic/remote-operations-management-rom)
- [Testing (5)](https://blog.3sharecorp.com/topic/testing)
- [Webinars (5)](https://blog.3sharecorp.com/topic/webinars)
- [AI (4)](https://blog.3sharecorp.com/topic/ai)
- [Adobe Summit (4)](https://blog.3sharecorp.com/topic/adobe-summit)
- [Personalization (4)](https://blog.3sharecorp.com/topic/personalization)
- [Sanity (4)](https://blog.3sharecorp.com/topic/sanity)
- [Structured Data (4)](https://blog.3sharecorp.com/topic/structured-data)
- [Design (3)](https://blog.3sharecorp.com/topic/design)
- [Headless (3)](https://blog.3sharecorp.com/topic/headless)
- [Leadership (3)](https://blog.3sharecorp.com/topic/leadership)
- [Quality Assurance (3)](https://blog.3sharecorp.com/topic/quality-assurance)
- [AEM Smart Tags (2)](https://blog.3sharecorp.com/topic/aem-smart-tags)
- [Award (2)](https://blog.3sharecorp.com/topic/award)
- [Content Fragments (2)](https://blog.3sharecorp.com/topic/content-fragments)
- [Evolve (2)](https://blog.3sharecorp.com/topic/evolve)
- [Evolve19 (2)](https://blog.3sharecorp.com/topic/evolve19)
- [Integrations (2)](https://blog.3sharecorp.com/topic/integrations)
- [Migration (2)](https://blog.3sharecorp.com/topic/migration)
- [QA (2)](https://blog.3sharecorp.com/topic/qa)
- [UX (2)](https://blog.3sharecorp.com/topic/ux)
- [AEM as a Cloud Service (1)](https://blog.3sharecorp.com/topic/aem-as-a-cloud-service)
- [AWS (1)](https://blog.3sharecorp.com/topic/aws)
- [Accessibility (1)](https://blog.3sharecorp.com/topic/accessibility)
- [Adobe Center of Excellence (1)](https://blog.3sharecorp.com/topic/adobe-center-of-excellence)
- [Apache (1)](https://blog.3sharecorp.com/topic/apache)
- [CDN (1)](https://blog.3sharecorp.com/topic/cdn)
- [ContextHub (1)](https://blog.3sharecorp.com/topic/contexthub)
- [CraftCMS (1)](https://blog.3sharecorp.com/topic/craftcms)
- [Digital Commerce (1)](https://blog.3sharecorp.com/topic/digital-commerce)
- [Digital Experience Solution Partner of the Year (1)](https://blog.3sharecorp.com/topic/digital-experience-solution-partner-of-the-year)
- [Extracirricular (1)](https://blog.3sharecorp.com/topic/extracirricular)
- [Invasion Test (1)](https://blog.3sharecorp.com/topic/invasion-test)
- [LLM (1)](https://blog.3sharecorp.com/topic/llm)
- [Microdata (1)](https://blog.3sharecorp.com/topic/microdata)
- [Rich Snippets (1)](https://blog.3sharecorp.com/topic/rich-snippets)
- [SEO (1)](https://blog.3sharecorp.com/topic/seo)
- [Security (1)](https://blog.3sharecorp.com/topic/security)
- [Vanity URL (1)](https://blog.3sharecorp.com/topic/vanity-url)
- [Web Server (1)](https://blog.3sharecorp.com/topic/web-server)
- [Workfront (1)](https://blog.3sharecorp.com/topic/workfront)

[see all](https://blog.3sharecorp.com/implementing-a-container-component-column-control-in-aem-spa-react#)

[![3SHARE_LOGO_WHITE_2018](https://blog.3sharecorp.com/hs-fs/hubfs/2017%20Website%20Assets/Logos/High%20Res/3SHARE_LOGO_WHITE_2018.png?width=266&height=54&name=3SHARE_LOGO_WHITE_2018.png "3SHARE_LOGO_WHITE_2018")](http://3sharecorp.com)

** [info@3sharecorp.com](mailto:info@3sharecorp.com)

** [US: +1 (888) 505-1625](tel:+18885051625)[tel:08003689636](tel:08003689636)

 

[**](https://www.linkedin.com/company/3-share-corporation) [**](https://www.youtube.com/@3share)

Copyright © 2026 [3|SHARE](https://www.3sharecorp.com/). All Rights Reserved.

[Cookie Settings](https://blog.3sharecorp.com/implementing-a-container-component-column-control-in-aem-spa-react#) ![](https://px.ads.linkedin.com/collect/?pid=8732449&fmt=gif)