Technical Talent →

Getting Started with AEM Universal Editor and AI-Assisted Authoring

AEM Universal Editor + AI

Overview : The Universal Editor is Adobe’s next-generation visual editing interface for AEM as a Cloud Service. Framework-agnostic and decoupled by design, it works with Edge Delivery Services pages, headless React and Next.js apps backed by Content Fragments, and any front end instrumented with UE metadata attributes. This blog shows how to extend it with AI.

What Is the Universal Editor?

The Universal Editor (UE) is Adobe’s next-generation visual editing interface for AEM as a Cloud Service. Unlike the classic Sites editor it is tightly coupled to AEM’s page model and the Universal Editor is framework-agnostic and decoupled by design.

It works with:

  • AEM Edge Delivery Services pages
  • Headless React / Next.js / Vue apps backed by AEM Content Fragments
  • Any front end instrumented with UE metadata attributes

The editor opens your live page in an iframe, lets authors click any component and edit it in-context, and writes changes back to either the AEM repository or a connected Google Doc depending on your delivery model.

Why It Matters for AI Integration

The Universal Editor exposes a REST-based Connections API and a plugin extension model built on Adobe’s App Builder UI framework. This means you can inject AI capabilities directly into the authoring surface not as a separate tool, but as a panel or action button inside the editor itself.

The three most impactful AI integrations for Universal Editor are:

  • In-context content generation : It authors click a component and generate or rewrite copy without leaving the editor
  • AI image variant generation : It triggers Adobe Firefly to produce on-brand image alternatives for a selected asset slot
  • Automated accessibility checking : It runs an AI pass on page content for WCAG 2.1 AA compliance before publish

Use Case 1 : In-Context AI Copywriting Panel

The Setup

Universal Editor extensions are built as App Builder UI extensions using the @adobe/uix-sdk. You define a panel that appears in the editor’s right rail and receives the currently selected component’s content as context.

// src/aem-cf-editor-1/web-src/src/components/AICopyPanel.jsx
import { useEffect, useState } from 'react';
import { attach } from '@adobe/uix-guest';
 
export default function AICopyPanel() {
  const [selection, setSelection] = useState(null);
  const [draft, setDraft]         = useState('');
  const [loading, setLoading]     = useState(false);
 
  useEffect(() => {
    attach({ id: 'ai-copy-panel' }).then(guest => {
      guest.host.editorState.getSelection().then(setSelection);
    });
  }, []);
 
  async function generateCopy() {
    setLoading(true);
    const res = await fetch('/api/generate-copy', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        currentText: selection?.content ?? '',
        tone: 'professional',
        maxWords: 80,
      }),
    });
    const { copy } = await res.json();
    setDraft(copy);
    setLoading(false);
  }
}

The App Builder action called by this panel:

// actions/generate-copy/index.js
const Anthropic = require('@anthropic-ai/sdk');
 
async function main(params) {
  const client = new Anthropic({ apiKey: params.ANTHROPIC_API_KEY });
  const message = await client.messages.create({
    model: 'claude-sonnet-4-6',
    max_tokens: 300,
    messages: [{
      role: 'user',
      content: `Rewrite in ${params.tone} tone, max ${params.maxWords} words.
Return only the rewritten text.
 
Original: ${params.currentText}`,
    }],
  });
  return { copy: message.content[0].text };
}

Use Case 2 : Adobe Firefly Image Variants

When an author selects an image component in Universal Editor, your extension surfaces a “Generate Variant” button that calls the Firefly API with the current image’s alt text as the prompt producing on-brand alternatives without leaving the editor.

// actions/firefly-variant/index.js
const fetch = require('node-fetch');
 
async function main(params) {
  const token = await getFireflyToken(params); // OAuth via Adobe IMS
 
  const res = await fetch('https://firefly-api.adobe.io/v3/images/generate', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'x-api-key': params.FIREFLY_CLIENT_ID,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      prompt: params.altText,
      numVariations: 3,
      size: { width: 1200, height: 630 },
      contentClass: 'photo',
    }),
  });
  const { outputs } = await res.json();
  return { variants: outputs.map(o => o.image.presignedUrl) };
}

Important : Firefly images are commercially safe by default — trained only on licensed Adobe Stock content. This makes them suitable for brand and product use without IP risk.

Use Case 3 : AI Accessibility Pre-Check

Before an author publishes, a toolbar button triggers an accessibility scan checking for missing alt text, poor colour contrast, improper heading hierarchy, and ARIA gaps. Issues are surfaced inline as highlights on the canvas.

// actions/accessibility-check/index.js
const Anthropic = require('@anthropic-ai/sdk');
 
async function main(params) {
  const client = new Anthropic({ apiKey: params.ANTHROPIC_API_KEY });
  const message = await client.messages.create({
    model: 'claude-sonnet-4-6',
    max_tokens: 1024,
    system: `You are a WCAG 2.1 AA accessibility auditor.
Analyse the provided HTML and return a JSON array of issues.
Each issue: { element, issue, severity: "error"|"warning", suggestion }`,
    messages: [{ role: 'user', content: `Page HTML:\n\n${params.pageHtml}` }],
  });
  return { issues: JSON.parse(message.content[0].text) };
}

Setting Up a Universal Editor Extension

Step 1 – Scaffold with the AIO CLI

aio app init my-ue-extension --template @adobe/aem-cf-editor-ui-ext-tpl

Step 2 – Register the extension

In app.config.yaml, declare your extension point:

extensions:
  aem/universal-editor/1:
    $include: src/universal-editor/ext.config.yaml

Step 3 – Configure the right rail panel

// src/universal-editor/web-src/src/index.js
import { register } from '@adobe/uix-guest';
 
register({
  id: 'ai-copy-panel',
  methods: {
    rightPanel: {
      addPanels() {
        return [{ id: 'ai-copy', title: 'AI Copy', url: '/ai-copy-panel' }];
      },
    },
  },
});

Step 4 – Deploy

aio app deploy

The extension appears automatically in Universal Editor for all authors in your AEM organisation no browser plugin installation required.

Key Differences from EDS Block AI Integration

 EDS Block AIUniversal Editor AI
Extension pointVanilla JS decorate()App Builder UI extension
Author interfaceSidekick event APIRight rail panel / toolbar
Content modelGoogle Docs tablesContent Fragments / page model
AI triggered byBlock render / lazy loadAuthor action in editor
Output goes toDOM (sanitised)Content Fragment / page properties
FrameworkVanilla JSReact + @adobe/uix-sdk

Project Setup Checklist

  • Create App Builder project in Adobe Developer Console
  • Scaffold extension with aio app init and the UE template
  • Add ANTHROPIC_API_KEY and FIREFLY_CLIENT_ID to App Builder environment params
  • Instrument your front end with data-aue-resource and data-aue-type attributes
  • Register extension in app.config.yaml under aem/universal-editor/1
  • Test AI panel in UE staging environment before deploying to production
  • Set Content-Security-Policy on your front end to allow https://experience.adobe.com
  • Validate AI-generated content updates persist correctly to the AEM content repo

Final Thoughts

The Universal Editor represents Adobe’s bet on a single, extensible authoring surface for every delivery model EDS, headless, traditional. For development teams, it means AI extensions built once with App Builder work across all project types without re-implementation.

The pattern is consistent: authors stay in context, AI does the repetitive cognitive work, and humans approve before anything publishes. The tooling has matured to the point where this is now a realistic production setup not a proof of concept.