Hi All,
I am working on Single Page Application where AEM is used for content authoring. Need inputs on the below queries.
1. Is it best practice to expose the path e.g /content/experience-fragment/sample/test/master/jcr:content/root/container.html in json for front end to hit and consume the HTML?
2. Is there any possibility to get Experience Fragments HTML in Sling model and pass it in JSON?
Thanks in advance!!
Solved! Go to Solution.
Views
Replies
Total Likes
Hi @Lakshmi08 ,
When integrating AEM with a Single Page Application (SPA), particularly regarding Experience Fragments (XF), there are a few best practices and considerations to take into account. Let's address your queries:
Directly exposing paths like /content/experience-fragment/sample/test/master/jcr:content/root/container.html for the frontend to consume the HTML is generally not recommended. Here are some reasons why:
Instead, consider these alternatives:
Yes, it's possible to get the HTML of Experience Fragments within a Sling model and then include this in a JSON response. This approach can encapsulate the HTML content in a structured JSON format, offering better control and flexibility.
Here's a simplified example of how you might implement this:
@Model(adaptables = Resource.class,
adapters = { XFModel.class, ComponentExporter.class },
resourceType = "yourapp/components/xfslingmodel")
@Exporter(name = "jackson", extensions = "json")
public class XFModelImpl implements XFModel {
@Self
private Resource resource;
@SlingObject
private ResourceResolver resourceResolver;
@ValueMapValue(name = "xfPath")
private String xfPath;
@Override
public String getExperienceFragmentHtml() {
try {
Resource xfResource = resourceResolver.getResource(xfPath + "/jcr:content/root");
if (xfResource != null) {
// Render the Experience Fragment as HTML
StringWriter writer = new StringWriter();
// Assume you have a custom renderer service that can render a resource as HTML
rendererService.render(xfResource, writer);
return writer.toString();
}
} catch (Exception e) {
// Handle exceptions
}
return "";
}
@Override
public String getExportedType() {
return resource.getResourceType();
}
}
In this model:
For SPA integrations with AEM, it’s best to utilize JSON APIs to keep the system decoupled and secure. Sling models can be effectively used to fetch and include Experience Fragment HTML in JSON responses, providing a structured and controlled way to expose content to the frontend. This approach maintains flexibility and performance while adhering to best practices in modern web development.
Hi @Lakshmi08 ,
When integrating AEM with a Single Page Application (SPA), particularly regarding Experience Fragments (XF), there are a few best practices and considerations to take into account. Let's address your queries:
Directly exposing paths like /content/experience-fragment/sample/test/master/jcr:content/root/container.html for the frontend to consume the HTML is generally not recommended. Here are some reasons why:
Instead, consider these alternatives:
Yes, it's possible to get the HTML of Experience Fragments within a Sling model and then include this in a JSON response. This approach can encapsulate the HTML content in a structured JSON format, offering better control and flexibility.
Here's a simplified example of how you might implement this:
@Model(adaptables = Resource.class,
adapters = { XFModel.class, ComponentExporter.class },
resourceType = "yourapp/components/xfslingmodel")
@Exporter(name = "jackson", extensions = "json")
public class XFModelImpl implements XFModel {
@Self
private Resource resource;
@SlingObject
private ResourceResolver resourceResolver;
@ValueMapValue(name = "xfPath")
private String xfPath;
@Override
public String getExperienceFragmentHtml() {
try {
Resource xfResource = resourceResolver.getResource(xfPath + "/jcr:content/root");
if (xfResource != null) {
// Render the Experience Fragment as HTML
StringWriter writer = new StringWriter();
// Assume you have a custom renderer service that can render a resource as HTML
rendererService.render(xfResource, writer);
return writer.toString();
}
} catch (Exception e) {
// Handle exceptions
}
return "";
}
@Override
public String getExportedType() {
return resource.getResourceType();
}
}
In this model:
For SPA integrations with AEM, it’s best to utilize JSON APIs to keep the system decoupled and secure. Sling models can be effectively used to fetch and include Experience Fragment HTML in JSON responses, providing a structured and controlled way to expose content to the frontend. This approach maintains flexibility and performance while adhering to best practices in modern web development.
Apache Sling Models features a exporter, leveraging the Jackson framework, which can serialize models into JSON. Adobe's new core components are designed with Sling Models, allowing for the creation of a headless AEM solution using just these core components. When using Adobe's core page component and editable templates, you can simply replace ".html" with ".model.json" to obtain a JSON representation of the page structure (including resourceType and all utilized components), provided your Apache Dispatcher module rules permit access to .model.json. For example: https://example.com/home.model.json.
With the Jackson Exporter, there's no special processing; all getter properties of your Sling Models class will be exposed and serialized into JSON. Therefore, if you perform any logic in your @PostConstruct method and then set the property, the computed value will appear in your JSON output.
Hi,
The Experience Fragment will most likely use the ComponentExporter class. Therefore, you can utilize the ".json" extension of the XF to obtain a JSON representation of it (see this: https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/need-to-read-export-json-o...). However, the optimal method for exposing content through APIs is via GraphQL and leveraging Content Fragments. While this isn't the sole approach, you could also employ the Sling Model exporter. Yet, for the best strategy in presenting data in a headless manner, I recommend considering GraphQL.
Addressing your questions:
1. You can expose the /content/experience-fragments path. However, ideally, you should consider adding a redirection to simplify and hide the full resource path.
2. YES, you could read the XF, perform cleanup manipulations, and then expose it via Sling Model Exporter or a Servlet. You can refer to these classes: https://developer.adobe.com/experience-manager/reference-materials/6-4/javadoc/com/adobe/cq/xf/Exper... and https://developer.adobe.com/experience-manager/reference-materials/6-4/javadoc/com/adobe/cq/xf/Exper...
Hope this helps
Hope this helps.
@Lakshmi08 Did you find the suggestions from users helpful? Please let us know if more information is required. Otherwise, please mark the answer as correct for posterity. If you have found out solution yourself, please share it with the community.