create-site

Creates a new AEM Edge Delivery site from scratch — GitHub repo from the boilerplate, aem-code-sync installation, initial DA content (nav, footer, homepage),…

INSTALLATION
npx skills add https://github.com/adobe/skills --skill create-site
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

Create a New AEM Edge Delivery Site

This skill walks through the full onboarding flow for a new AEM Edge Delivery site. It handles everything that can be automated and clearly signals the steps that require human action.

When to Use This Skill

Use this skill when:

  • A user wants to create a brand-new AEM Edge Delivery site from scratch
  • A user asks to "set up a new site", "create a new EDS project", or "onboard a new site"
  • No GitHub repository or DA content exists yet for the project

Do NOT use this skill for:

  • Importing or migrating existing pages (use page-import skill)
  • Building or modifying blocks on an existing site (use content-driven-development skill)

Prerequisites

  • A GitHub account with permission to create repositories in the target org
  • An Adobe IMS account with access to DA (da.live)
  • gh CLI authenticated (gh auth status) or a GitHub personal access token with repo scope
  • Node.js (for DA token management via da-auth-helper)

Related Skills

  • page-import — Import existing pages into the newly created site
  • content-driven-development — Build and modify blocks once the site exists
  • building-blocks — Implement new block code

Step 0: Create TodoList

Create a checklist to track progress (use your agent's task-tracking tool if available):

  • Gather inputs — org, repo name, site name collected
  • Create GitHub repository — repo created from boilerplate template
  • Install aem-code-sync (human action) — GitHub App installed on repo
  • Authenticate with DA — valid IMS token obtained
  • Create initial content in DA — nav, footer, index created
  • Trigger preview — all three paths return 200/201
  • Hand off — preview URL and DA links delivered to user

Step 1: Gather Inputs

Ask the user for the following. Do not proceed until all required inputs are provided.

  • GitHub org — the GitHub organization or username where the repo will be created (e.g. my-org)
  • Project name — the repository name, lowercase, hyphens only (e.g. my-site)
  • Site name — the human-readable name used in content (e.g. My Site). If not provided, derive it from the project name.

Store as: {{ORG}}, {{REPO}}, {{SITE_NAME}}

Step 2: Create GitHub Repository

Create a new repository using the adobe/aem-boilerplate template.

Option A — GitHub CLI (preferred, handles auth automatically):

gh repo create {{ORG}}/{{REPO}} \

  --template adobe/aem-boilerplate \

  --description "{{SITE_NAME}} — AEM Edge Delivery site" \

  --public

Check if gh is available with gh auth status. If not authenticated, run gh auth login first.

**Option B — GitHub API (if gh CLI is not available):**

POST https://api.github.com/repos/adobe/aem-boilerplate/generate

Authorization: Bearer {{GITHUB_TOKEN}}

Content-Type: application/json

{

  "owner": "{{ORG}}",

  "name": "{{REPO}}",

  "description": "{{SITE_NAME}} — AEM Edge Delivery site",

  "private": false,

  "include_all_branches": false

}

To obtain a token: https://github.com/settings/tokens/new — scope: repo.

Success: HTTP 201 (API) or exit code 0 (CLI). The repo is now live at https://github.com/{{ORG}}/{{REPO}}.

Step 3: Install aem-code-sync (human action required)

The aem-code-sync GitHub App connects the repository to AEM's content delivery pipeline. This step cannot be automated — the user must complete it in the browser.

Tell the user:

Action required: Install the AEM Code Sync app on your new repository.

  • Under "Repository access", select Only select repositories
  • Choose {{ORG}}/{{REPO}} from the list
  • Click Save

Reply "done" when complete.

Wait for confirmation before proceeding.

Verify: After confirmation, check that https://admin.hlx.page/status/{{ORG}}/{{REPO}}/main/ returns a valid JSON response (not 404). If it does, the app is correctly installed.

Step 4: Authenticate with DA

DA requires Adobe IMS authentication. Choose the appropriate path:

Option A — da-auth-helper (preferred)

da-auth-helper (https://github.com/adobe-rnd/da-auth-helper) caches IMS tokens at ~/.aem/da-token.json. Always check the cache first before triggering a new OAuth flow.

  • Check for a valid cached token:
node -e "

  const fs = require('fs');

  const p = process.env.HOME + '/.aem/da-token.json';

  if (!fs.existsSync(p)) { console.log('No cache'); process.exit(1); }

  const t = JSON.parse(fs.readFileSync(p));

  console.log('Valid:', t.expires_at > Date.now());

  console.log('Expires:', new Date(t.expires_at).toISOString());

"
  • If valid, capture the token and skip to Step 5:
DA_TOKEN=$(node -e "const t = require(process.env.HOME + '/.aem/da-token.json'); process.stdout.write(t.access_token);")
  • If missing or expired, install da-auth-helper from GitHub (it is not published to npm) and refresh:
npm install -g github:adobe-rnd/da-auth-helper

da-auth-helper token

This opens a browser for Adobe IMS login and writes the new token to ~/.aem/da-token.json. Then capture it as in step 2.

Option B — DA MCP is configured

If the DA MCP server is available, trigger the authentication tool to start the OAuth flow and share the authorization URL with the user.

Option C — Manual token

Ask the user to obtain an IMS token from their browser (e.g. from the DA network tab or an existing session) and paste it. Store as {{DA_TOKEN}}.

Step 5: Create Initial Content in DA

Create the three mandatory pages every EDS site requires. Use the templates below exactly — they are pre-validated for EDS compliance.

Option A — DA MCP:

Call the DA create source tool three times with the content below.

Option B — DA API:

Write each file to a temp file first, then POST using @ syntax. Inline multiline content with -F 'data=...' causes curl to fail (exit 26). Use /usr/bin/curl explicitly to avoid PATH resolution issues in subshells.

cat > /tmp/nav.html << 'EOF'

<nav content>

EOF

/usr/bin/curl -s -o /dev/null -w "%{http_code}" -X POST "https://admin.da.live/source/{{ORG}}/{{REPO}}/nav.html" \

  -H "Authorization: Bearer {{DA_TOKEN}}" \

  -F "data=@/tmp/nav.html;type=text/html"

Repeat for footer.html and index.html.

Verify: After each POST, expect HTTP 201. If you get 401, the token has expired — return to Step 4.

nav.html

<main>

  <div>

    <p><a href="/">{{SITE_NAME}}</a></p>

  </div>

  <div>

    <ul>

      <li><a href="/">Home</a></li>

    </ul>

  </div>

  <div></div>

</main>

footer.html

<main>

  <div>

    <p>© 2024 {{SITE_NAME}}. All rights reserved.</p>

  </div>

</main>

index.html

<main>

  <div>

    <h1>Welcome to {{SITE_NAME}}</h1>

    <p>Your new site is ready. Start editing this page in DA.</p>

  </div>

</main>

Step 6: Trigger Preview

Preview pulls the DA content into the AEM delivery pipeline and makes it accessible on the .aem.page domain.

DA-sourced content requires the Bearer token on preview requests — even for public repos. Use /usr/bin/curl explicitly.

/usr/bin/curl -s -o /dev/null -w "%{http_code}" -X POST "https://admin.hlx.page/preview/{{ORG}}/{{REPO}}/main/nav" \

  -H "Authorization: Bearer {{DA_TOKEN}}"

/usr/bin/curl -s -o /dev/null -w "%{http_code}" -X POST "https://admin.hlx.page/preview/{{ORG}}/{{REPO}}/main/footer" \

  -H "Authorization: Bearer {{DA_TOKEN}}"

/usr/bin/curl -s -o /dev/null -w "%{http_code}" -X POST "https://admin.hlx.page/preview/{{ORG}}/{{REPO}}/main/" \

  -H "Authorization: Bearer {{DA_TOKEN}}"

Success: HTTP 200 or 201 for each. The homepage is now live at:

https://main--{{REPO}}--{{ORG}}.aem.page/

Step 7: Confirm and Hand Off

Tell the user:

Your site is ready!

  • Preview: https://main--{{REPO}}--{{ORG}}.aem.page/
  • Browse content in DA: https://da.live/#/{{ORG}}/{{REPO}}/
  • Edit homepage: https://da.live/edit#/{{ORG}}/{{REPO}}/index
  • Edit nav: https://da.live/edit#/{{ORG}}/{{REPO}}/nav
  • Edit footer: https://da.live/edit#/{{ORG}}/{{REPO}}/footer
  • GitHub repo: https://github.com/{{ORG}}/{{REPO}}

To start developing locally:

git clone https://github.com/{{ORG}}/{{REPO}}.git

cd {{REPO}}

npm install

aem up

What would you like to do next — add more pages, customize a block, or set up a custom domain?

Troubleshooting

SymptomLikely causeFix
Step 2 returns 422Repo name already existsAsk user for a different name
Step 3 verify returns 404aem-code-sync not installedRe-send the installation URL
Step 4 cached token missing/expiredNo prior DA session on this machineInstall da-auth-helper from GitHub (npm install -g github:adobe-rnd/da-auth-helper) and run da-auth-helper token
Step 5 curl exits with code 26Inline multiline content in -F flagWrite content to a temp file and use @/tmp/file.html syntax
Step 5 returns 401Expired or missing IMS tokenRe-check ~/.aem/da-token.json expiry; ask user for a fresh token
Step 5 returns 403Token lacks permission for this org/repoConfirm the user has write access to {{ORG}}/{{REPO}} in DA
Step 6 returns 401DA-sourced content requires auth on previewAdd -H "Authorization: Bearer {{DA_TOKEN}}" to preview requests
Step 6 returns 404aem-code-sync not installed correctlyVerify Step 3, then retry
curl: command not found in scriptsPATH not resolved in subshellUse /usr/bin/curl explicitly
Preview URL shows blank pagenav or index not previewedRe-run Step 6 for the failing path

Reference

DA URL patterns

  • Browse folder: https://da.live/#/{{org}}/{{repo}}{{folder-path}}
  • Edit HTML document: https://da.live/edit#/{{org}}/{{repo}}{{path-without-extension}}
  • Edit JSON/sheet: https://da.live/sheet#/{{org}}/{{repo}}{{path-without-extension}}
BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card