Expand my Community achievements bar.

Submissions are now open for the 2026 Adobe Experience Maker Awards.

Content updates to AEM instance

Avatar

Level 1

Hi Everyone,

I have a requirement to move our customized Adobe components into a proxy folder and update all content that currently references these components so they point to the new proxy versions.

Example:

  • Current component: button

  • New proxy component: buttongl

This means I need to update all pages to use the proxy component by modifying the sling:resourceType for every instance of the old button.

Adobe Support recommended importing the content into code, applying the updates there, and then deploying through Cloud Manager (since we’re on AEM Cloud).

I tried this approach in a demo project, but so far I don’t see my changes reflected in the AEM instance — currently testing on localhost.

 

Steps I followed:

  1. Created a demo project, authored a new content page, and synced back to source code for making changes

RatheeshVa_0-1758770958459.png

 

 

2: Filter.xml

RatheeshVa_1-1758770958483.png

 

 

3: build using command: mvn clean install -PautoInstallSinglePackage

4: Verify the changes are reflected in crxde

RatheeshVa_2-1758770958516.png


Content.xml

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
    jcr:primaryType="cq:Page">
    <jcr:content
        cq:lastModified="{Date}2025-09-23T20:13:14.268-07:00"
        cq:lastModifiedBy="admin"
        cq:template="/conf/demo/settings/wcm/templates/page-content"
        jcr:primaryType="cq:PageContent"
        jcr:title="Ratheesh Page"
        sling:resourceType="demo/components/page">
        <root
            jcr:primaryType="nt:unstructured"
            sling:resourceType="demo/components/container"
            layout="responsiveGrid">
            <container
                jcr:primaryType="nt:unstructured"
                sling:resourceType="demo/components/container"
                layout="responsiveGrid">
                <title
                    jcr:primaryType="nt:unstructured"
                    sling:resourceType="demo/components/title"/>
                <container
                    jcr:primaryType="nt:unstructured"
                    sling:resourceType="demo/components/container"
                    layout="responsiveGrid">
                    <image
                        jcr:created="{Date}2025-09-23T20:12:15.392-07:00"
                        jcr:createdBy="admin"
                        jcr:lastModified="{Date}2025-09-23T20:12:15.392-07:00"
                        jcr:lastModifiedBy="admin"
                        jcr:primaryType="nt:unstructured"
                        sling:resourceType="demo/components/image"
                        fileReference="/content/dam/digital/websites/products/camouflage-nanohybrid-composite/clinical-images/case-1/AntBelleglassafter.jpg"
                        imageFromPageImage="false"/>
                    <button
                        jcr:created="{Date}2025-09-23T20:12:22.489-07:00"
                        jcr:createdBy="admin"
                        jcr:lastModified="{Date}2025-09-23T20:13:14.262-07:00"
                        jcr:lastModifiedBy="admin"
                        jcr:primaryType="nt:unstructured"
                        jcr:title="Ratheesh Button2"
                        sling:resourceType="demo/components/button"
                        linkTarget="_self"/>
                    <button_451314813
                        jcr:created="{Date}2025-09-23T20:12:36.223-07:00"
                        jcr:createdBy="admin"
                        jcr:lastModified="{Date}2025-09-23T20:12:56.013-07:00"
                        jcr:lastModifiedBy="admin"
                        jcr:primaryType="nt:unstructured"
                        jcr:title="Ratheesh Button"
                        sling:resourceType="demo/components/buttongl"
                        linkTarget="_self"/>
                </container>
            </container>
        </root>
    </jcr:content>
</jcr:root>

 

filter.xml:

<?xml version="1.0" encoding="UTF-8"?>
<workspaceFilter version="1.0">
    <filter root="/content/demo/us/en/RatheeshPage/jcr:content/root/container/container/button_451314813" mode="update_properties"/>
    <filter root="/conf/demo" mode="merge"/>
    <filter root="/content/demo" mode="merge">
    </filter>
    <filter root="/content/dam/demo" mode="merge">
        <exclude pattern="/content/dam/demo(/.*)?"/>
        <include pattern="/content/dam/demo/jcr:content(/.*)?"/>
    </filter>
    <filter root="/content/dam/demo/asset.jpg" mode="merge"/>
    <filter root="/content/experience-fragments/demo" mode="merge"/>
</workspaceFilter>


 

4 Replies

Avatar

Level 5

Hi @RatheeshVa 

Why you don’t see the property update

  1. Packages don’t overwrite by default
    Your filter.xml has mode="merge" or update_properties. These modes are non-destructive — they won’t overwrite properties that already exist in the repo. If a node is already in /content/..., your package won’t replace its sling:resourceType.
  2. Author-created content wins
    Any page authored in AEM takes precedence over package content. AEM assumes /content is owned by authors, not developers, so it protects it from being blown away by deployments.
  3. Local SDK behaves the same
    Even on localhost, unless you explicitly tell the filter to replace, AEM merges and leaves existing content untouched. That’s why you still see demo/components/button in CRXDE

Force Replace (not recommended for authored pages)

Change your filter.xml like this:

<filter root="/content/demo/us/en/RatheeshPage" mode="replace"/>

If you replace the whole page with your package, you’ll see buttongl in CRXDE.
But any edits made by authors in AEM will be wiped out every time you deploy.

or

Update only the node

Narrow the filter to just the button node and use replace:

<filter root="/content/demo/us/en/RatheeshPage/jcr:content/root/container/container/button" mode="replace"/>

That will overwrite only that button node.
But you’d need to repeat this for every instance across all pages → not scalable.

or else

Run a migration

Instead of packaging content in Git, update it inside the repository once

Groovy Console script (if ACS Commons is available):

def updated = 0
def query = "SELECT * FROM [nt:unstructured] WHERE [sling:resourceType] = 'demo/components/button'"
def result = session.workspace.queryManager.createQuery(query, "JCR-SQL2").execute()

result.nodes.each { node ->
    node.setProperty("sling:resourceType", "demo/components/buttongl")
    updated++
}
session.save()
println "Updated ${updated} button components."

This will immediately update all button nodes in your content repo → check CRXDE after running and you’ll see the change.

 

Hope this helpful 🙂

 

Regards,

Karishma.

 

 

Avatar

Level 1

Thank you for your quick and detailed reply.

I just tried the below filter, but now crxde is missing this button_451314813. 
Since I will be moving all custom components, I would like to replace the node property: sling resource type alone.

 

 <filter root="/content/demo/us/en/RatheeshPage/jcr:content/root/container/container/button_451314813" mode="replace"/>

 

RatheeshVa_0-1758776461301.png

 

 

Avatar

Level 5

Hi @RatheeshVa 

Use ACS Commons Tools 

  • CSV ResourceType Updater: You prepare a CSV mapping old → new sling:resourceType.
/content/demo/us/en/RatheeshPage/jcr:content/root/container/container/button_451314813,demo/components/buttongl
  • Upload it in the ACS Commons tool (/apps/acs-commons/content/page-tools/resource-type-updater.html).
  • It will bulk update the property without deleting the node.

or

Use a Groovy Script (if ACS Commons is available with Groovy Console, or you can run via CRXDE package)

def mappings = [
    "demo/components/button": "demo/components/buttongl",
    "demo/components/image": "demo/components/imagegl"
]

def updated = 0
def query = "SELECT * FROM [nt:unstructured] WHERE [sling:resourceType] IS NOT NULL"
def result = session.workspace.queryManager.createQuery(query, "JCR-SQL2").execute()

result.nodes.each { node ->
    def current = node.getProperty("sling:resourceType").string
    if (mappings.containsKey(current)) {
        node.setProperty("sling:resourceType", mappings[current])
        updated++
    }
}
session.save()
println "Updated ${updated} components"

This may avoild filter.xml problem.

 

Regards,

Karishma.

 

Avatar

Community Advisor

@RatheeshVa 

 

If you have ACS AEM Commons, you can create a generic service to update property. Example: 

https://kiransg.com/2021/12/10/bulk-add-update-and-delete-properties-in-aem-without-using-groovy-con...

 

Concept would be similar to https://adobe-consulting-services.github.io/acs-aem-tools/features/csv-resource-type-updater/index.h...

 

This generic service can then be used to replace values for various properties 


Aanchal Sikka