App Docs

Adobe Experience Manager

Documentation for the Laioutr Adobe Experience Manager app. Read AEM's assets and their Dynamic Media addresses, so URL mapping can move every original into Assetr without a CSV.

Overview

The @laioutr-app/aem app connects a Laioutr project to Adobe Experience Manager (AEM). It reads the assets of AEM's DAM, with the Dynamic Media (Scene7) address each one was published on, so URL mapping can move every original into Assetr and keep each old URL answering — no CSV export needed.

The app only reads. It never writes to AEM, and it reads only what the credential you give it may read.

The app supports AEM as a Cloud Service. AEM 6.5 follows. It is free, like Laioutr's other connectors.

What it supports

AEM versionAEM as a Cloud Service, read on its author tier.
Signing inAn access token (such as the 24-hour local development token), or OAuth Server-to-Server keys that renew by themselves.
What it readsEvery asset (dam:Asset) below a DAM folder you choose: its path, name, file type, size, last change, title, description, tags, and the Dynamic Media file it was published as.
Old URLsBuilt for every asset published to Dynamic Media, on your own media host: /is/image/… for images, /is/content/… for PDFs, SVGs, videos and other files.
OriginalsThe file stored in AEM, at full size, served to Laioutr through a signed link of your storefront.
Where it is usedURL mapping's From: AEM import.
Large DAMsAssets are read in pages of 100, in the order AEM created them, so a DAM of any size is read to the end and a new asset added during the read is not missed.

Not supported yet: Content Fragments, pages, asset renditions and metadata beyond the fields above, delivery through Dynamic Media with OpenAPI, and change notifications from AEM.

What you need

  • The author host of your AEM as a Cloud Service environment, as Cloud Manager shows it, such as author-p12345-e67890.adobeaemcloud.com. Publish hosts do not answer the queries the app needs.
  • A way to sign in: an access token for a first look, or OAuth Server-to-Server keys for everything that runs by itself.
  • The host your old Dynamic Media URLs answered on, such as media.example.com.
  • A storefront environment of the project the app can be installed and deployed on. It must answer from the internet without a password while an import runs: each original is fetched through it.

Install and configure

  1. In the Cockpit, open the project's environment → Package Management, add Adobe Experience Manager and save.
  2. Open the environment's Configuration in the menu, choose the app, and fill in the sections below. Each sign-in section has a Test connection button that checks the values before you save. (Package Management → Configure shows the same fields, without the tests.)
  3. Deploy the environment. Until the app has an author host and a deploy has run, URL mapping does not offer AEM for it.

Connection

FieldWhat to enter
Author hostThe author tier of your AEM as a Cloud Service environment, without https://.
Sign in withAn access token or OAuth Server-to-Server keys. Fill in the matching section below; the other one is ignored.

Access token

FieldWhat to enter
Access tokenThe accessToken value of the downloaded JSON, without Bearer.

Where to get it: in Cloud Manager, open the environment's Developer Console, then Integrations → Local token → Get Local Development Token.

  • It is valid for 24 hours. The app stops reading once it expires, and says so.
  • It reads everything its user may read — the person who generated it. Adobe recommends it for development only, so switch to OAuth keys before a real migration.

Test connection lists one asset with the token and passes when AEM answers with it.

OAuth Server-to-Server

FieldWhat to enter
Client IDThe credential's client ID.
Client secretThe credential's client secret.
ScopesAs the credential's page lists them, separated by commas.
IMS hostThe credential's IMS endpoint. Leave empty for ims-na1.adobelogin.com.

Setting it up in Adobe:

  1. In the Adobe Developer Console, add an OAuth Server-to-Server credential to a project that has AEM.
  2. Copy its client ID, client secret and scopes into the settings above.
  3. Make one call — press Test connection. AEM creates the credential's technical account at that moment, in the read-only Contributors group.
  4. In AEM, under Tools → Security, give that technical account read access to the DAM folders the migration needs: the DAM folder below, /content/dam/dynamic-media where Dynamic Media keeps logos and similar assets, and any folder the access report shows as empty. Read only.

The app asks Adobe for a new token by itself, five minutes before the current one expires.

Test connection asks Adobe IMS for a token with the keys and passes when one is returned. It checks the keys, not what the technical account may read — the access report does that.

Assets

FieldWhat to enter
DAM folderAssets are read below this folder. Leave empty for the whole DAM (/content/dam).
Dynamic Media hostYour own host the old Dynamic Media URLs answered on, such as media.example.com. The old URL of each asset is built on it.

Use your own host, not an Adobe one (s7d1.scene7.com and similar): only a domain you own can be switched to Laioutr once AEM is gone. See Switch the DNS.

What the credential may read

AEM does not refuse an asset a user may not read; it leaves it out of the answer. A credential with too little access therefore looks like a DAM with fewer assets, and nothing fails.

Before the first import, Laioutr runs an access report with your credential and sends you the result: the user AEM signs it in as, when its token expires, and for the DAM folder, /content/dam/dynamic-media and any other folder you name, how many assets are readable and how many of them were published to Dynamic Media. A folder that shows no assets usually means its read access is missing. The report only reads.

What is imported

In URL mapping, New import → From: AEM reads the assets through the app, in pages, in the background. For each asset published to Dynamic Media:

  • The old URL is the one Dynamic Media answered on, on the Dynamic Media host above.
  • The file is the original stored in AEM, never the smaller copy Dynamic Media served.
  • An old URL that an earlier import moved already (from a Dynamic Media CSV, say) is moved again with the AEM original. It keeps answering with the earlier file until the original is stored; the earlier file stays in your Assetr library.

Assets AEM never published to Dynamic Media have no old URL to keep, and are not imported.

Security

  • The access token and the client secret are kept as secrets: they stay on the storefront's server and never reach a browser.
  • An original is served only to a link signed with a key derived from the project's secret. A link is valid for 30 days; an expired one is refused, and reading the assets again in a new import gives every asset a new one.
  • The link hands out the file as a download, never as a page, and only for an asset below the DAM folder.
  • An original AEM answers with a redirect to its own file storage is fetched from there without sending your credential along.

Troubleshooting

What you seeWhat to do
URL mapping says no storefront of the project offers AEM's assetsFill in the author host and the sign-in, save, and deploy the environment again.
Test connection of the access token failsThe token expired (after 24 hours) or was copied with Bearer. Get a new one and paste only its value.
Test connection of the OAuth keys failsCheck the client ID, secret and scopes against the credential's page, and the IMS host if the credential names one.
The import reads fewer assets than AEM holdsThe credential may not read some folders. Give it read access there and import again; what was moved is not moved twice.
The import stops because AEM refused the credentialThe token expired or the keys were revoked. Set a new token or keys, deploy, and start the import again.
The import stops because the storefront is unreachableThe storefront is behind a password, or not deployed. Remove the password for the time of the import, or choose another environment.

A busy AEM (429, 502, 503, 504) or a timeout is not a stop: the page is asked for again later.

For developers

The package is a Nuxt module configured under the key @laioutr-app/aem. In a Laioutr project the Cockpit writes these options from the settings above; in a project of your own, set them in nuxt.config.ts:

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@laioutr-core/frontend-core', '@laioutr-core/orchestr', '@laioutr-app/aem'],
  '@laioutr-app/aem': {
    authorHost: process.env.AEM_AUTHOR_HOST!,
    authMode: 'oauth',
    clientId: process.env.AEM_CLIENT_ID,
    clientSecret: process.env.AEM_CLIENT_SECRET,
    scopes: process.env.AEM_SCOPES,
    damRoot: '/content/dam',
    mediaHost: 'media.example.com',
  },
});
OptionTypeDescription
authorHoststringThe author host. When empty, the app registers nothing.
authMode'token' | 'oauth'How the app signs in.
accessTokenstringFor token. Secret.
clientId, clientSecret, scopesstringFor oauth. The secret is secret.
imsHoststringFor oauth; ims-na1.adobelogin.com when unset.
damRootstringThe DAM folder; /content/dam when unset.
mediaHoststringThe Dynamic Media host old URLs are built on.

Source entity Asset

The app offers AEM's assets as source entities of type Asset through frontend-core's source entity API. Each entity is identified by its DAM path, carries one locale (und), and gets a new version whenever any of its values changes.

FieldDescription
pathThe DAM path, such as /content/dam/brand/chair.jpg.
nameThe file name.
mimeTypeThe file type.
sizeThe original's size in bytes.
modifiedAtWhen the asset last changed.
scene7FileThe Dynamic Media file it was published as (dam:scene7File).
oldUrlIts Dynamic Media URL on mediaHost.
originalUrlThe signed link its original is served on (/api/aem/original/<token>).
title, description, tagsIts metadata in AEM.

A field AEM has no value for is left out.

Changelog

All changelogs are managed in CHANGELOG.md in the package's GitHub repository. This app does not currently have a public repository under the Laioutr organization; when it is published there, use that repo's CHANGELOG.md for release notes.

Copyright © 2026 Laioutr GmbH