Publishing AEM Content Fragments to Edge Delivery Services

AEM content fragments are used to create, manage, and deliver content across multiple channels. Until recently, publishing content fragments to Edge Delivery Services only embedded a reference to the content fragment—not the actual content—in the semantic HTML. This can limit a LLM agents’ ability to ingest and understand the content or create a meaningful search index for a page.

With the approach described next, you can publish AEM Content Fragments to Edge Delivery Services as self-contained semantic HTML.

Why Does This Matter?

1. LLM/SEO Optimization

LLM and SEO optimization improve because content fragments are now published as self-contained semantic HTML. Previously, only links to fragments were included, so automated agents like search engines and language models could not access the full content. Now, the complete content is directly available without requiring JavaScript.

2. Omnichannel Delivery

Omnichannel delivery like banners, press releases, blog posts etc. can be managed and published as full web pages instead of only as headless content. Edge Delivery Services acts as the “head” for the headless CMS, providing HTML output for any channel.

3. Simplified Workflow

In the current approach, GraphQL endpoints and queries must be defined and published together with the fragments. For each content fragment model, a separate block is created and then added to an AEM page. Finally, the page itself is published, containing only a reference to the content fragment rather than the fragment’s full content.

The new approach streamlines this significantly. Instead of working with GraphQL endpoints, you define path mapping and overlay directly in the site configuration. The json2html service is then configured, and a Mustache template is applied to transform the JSON output of the fragments into HTML.

With this setup, the content fragments can be published directly as HTML, eliminating the need for additional blocks, queries or pages.

How to Set It Up

As a prerequisite you need:

For our example we are going to use a content fragment model for press releases with fields like title, author, text and image.

Next we create Content Fragments in a dedicated assets folder (e.g., below press) using the press release model.


Step 1: Configure Path Mapping and Overlay in Configuration Service

In the Configuration Service, define the published path for your content fragments. In our example we publish them directly below /press.

"public": {
    "paths": {
      "mappings": [
        "/content/xwalk-omnichannel/:/",
        "/content/dam/xwalk-omnichannel/press/:/press/"
      ]
    }
  }

Add an overlay to the content source section in your org’s config, pointing to the json2html service.

"content": {
    "source": {
      "url": "https://author-pXXXX-eXXXX.adobeaemcloud.com/bin/franklin.delivery/adobe-rnd/xwalk-omnichannel/main",
      "type": "markup",
      "suffix": ".html"
    },
    "overlay": {
      "url": "https://json2html.adobeaem.workers.dev/adobe-rnd/xwalk-omnichannel/main",
      "type": "markup"
    },
  }

The URL format for the json2html service is:

https://json2html.adobeaem.workers.dev/ORG/SITE/BRANCH

How the overlay works:

Step 2: Configure the json2html Service

The following is the curl command to set up the service for our example use case:

curl --request POST \
 --url https://json2html.adobeaem.workers.dev/config/adobe-rnd/xwalk-omnichannel/main \
 --header 'Authorization: token <admin-api-token>' \
 --header 'Content-Type: application/json' \
 --data '[
    {
        "path": "/press/",
        "endpoint": "https://author-pXXXX-eXXXX.adobeaemcloud.com/api/assets/xwalk-omnichannel/press/{{id}}.json",
        "regex": "/[^/]+$/",
        "template": "/cf-templates/press.html",
        "relativeURLPrefix": "https://publish-pXXXX-eXXX.adobeaemcloud.com", 
	  "headers": {           
          "Accept": "application/json"
        },
        "forwardHeaders":[
            "Authorization"
        ]
    }
]

See the documentation for the json2html Service for a detailed description of the different configuration options. In short:

Step 3: Create a Mustache Template

Without a template, each property in your JSON is rendered as a <div>. To create a more meaningful semantic HTML for our press release example we define a template that renders:

<!DOCTYPE html>
<html>
  <head>
    <title>{{properties.title}}</title>
  </head>
  <body>
    <header></header>
    <main>
      <div>
        <div class="hero">
          <div>
            <div>
              <p>
                <picture>
                  <img src="{{{properties.elements.image.value}}}">
                </picture>
              </p>
              <h1>{{properties.elements.newsTitle.value}}</h1>
            </div>
          </div>
        </div>
        <p><strong>Author:</strong> {{properties.elements.author.value}}</p>
        <div class="columns">
          <div>
            <div>
              <p>
                <picture>
                  <img src="{{{properties.elements.image2.value}}}">
                </picture>
              </p>
            </div>
            <div>
              <p>{{{properties.elements.text.value}}}</p>
            </div>
            <div>
              <p>
                <picture>
                  <img src="{{{properties.elements.image3.value}}}">
                </picture>
              </p>
            </div>
          </div>
        </div>
      </div>
    </main>
    <footer></footer>
  </body>
</html>

Key Points:

Test Your Setup

For our example the output looks as follows:

Conclusion

By setting up an overlay using the json2html service, you can now publish AEM content fragments as self-contained semantic HTML to Edge Delivery Services. This simplifies omnichannel delivery and makes your content LLM-ready—all with minimal setup.