diff --git a/plugins/aem/edge-delivery-services/skills/snowflake/knowledge/methodology.md b/plugins/aem/edge-delivery-services/skills/snowflake/knowledge/methodology.md index 85b7f258..022a0a75 100644 --- a/plugins/aem/edge-delivery-services/skills/snowflake/knowledge/methodology.md +++ b/plugins/aem/edge-delivery-services/skills/snowflake/knowledge/methodology.md @@ -86,46 +86,47 @@ output/ └── da/.html ← DA-source body fragment ``` -**Rewrite relative asset paths.** When a source uses relative paths -like `assets/photos/foo.jpg`, `url(./images/bar.png)`, -``, they resolve against our serving -host (`localhost:3000/drafts/...` or -`----.aem.page//...`) — where they 404. -They need rewriting to one of three target forms, depending on -**asset strategy** (recorded in `decisions.json["assetStrategy"]`): - -1. **`absolute`** (default for publicly hosted sources): - `https:///path/to/assets/...`. Source host serves the - binaries directly; EDS preview sideloads any `` URL into - Media Bus on first preview (see da-content `media.md` §2). -2. **`vendor`** (local-only source, accepted repo size impact): - Copy the asset tree into `./assets/` in the repo. Template / - fragment / page-CSS refs become root-relative `/assets/...`. DA - cell refs use absolute branch URLs - (`https://----.aem.page/assets/...`). -3. **`da-media`** (cleanest long-term): - Upload binaries to DA `/media//` via the bundled - `/scripts/da-media-upload.mjs` script. Template / - fragment / page-CSS / DA cell refs all use - `https://content.da.live///media//`. The - uploader emits a `media-mapping.json` of local-path → - content.da.live URL that Generate consumes for the rewrites. - -| Aspect | absolute | vendor | da-media | -|---------------------------|-------------|--------------|--------------| -| Repo size | unchanged | +N MB | unchanged | -| Branch-independent assets | N/A | No | **Yes** | -| Local-only source | No | Yes | Yes | -| Initial-run effort | none | curl+sed | uploader | -| Tooling required | none | none | bundled `.mjs` | -| Reusable across runs | N/A | per-run | **Yes** | -| DA-cell image URL form | source host | branch URL | content.da.live | -| Delivered image URL | `./media_` (sideload) | `./media_` | `./media_` | - -For fonts specifically, even under `da-media`, place font files in Code -Bus `/fonts/.woff2` (or `.otf`) per da-content `media.md` -§13.2 decision tree. Fonts upload would be a DA media-bus mismatch -(SVG/PNG/JPG/MP4 are Media Bus; fonts are Content Bus). +**Asset handling is per-asset, decided mechanically.** The +`asset-collect.mjs` script (run in Phase 1) scans `index.html` for +in-scope asset references — raster images, videos, and fonts — and +assigns a per-asset strategy based on reachability and type: + +| Asset reachability | Asset type | Strategy | Destination | +|---|---|---|---| +| Stable CDN (fonts.gstatic.com, cdn.jsdelivr.net, etc.) | any | `absolute` — leave URL as-is | no download | +| Ephemeral host (claudeusercontent.com, etc.) | font | `vendor` — always download | `input/fonts/` → `/fonts/` | +| Ephemeral host | image, video | `da-media` — always download | `input/images/` or `input/videos/` | +| Reachable public host + public base URL | any | `absolute` — leave URL as-is | no download | +| Reachable public host + local base URL (snapshot) | font | `vendor` — download | `input/fonts/` → `/fonts/` | +| Reachable public host + local base URL (snapshot) | image, video | `da-media` — download | `input/images/` or `input/videos/` | +| Local / private IP | font | `vendor` — download | `input/fonts/` → `/fonts/` | +| Local / private IP | image, video | `da-media` — download | `input/images/` or `input/videos/` | + +**Never vendor images or videos into the git repo.** Binary content +assets belong in DA Media Bus, not Code Bus. Only code assets (fonts, +SVGs under 40KB, scripts, stylesheets) go in the git repo. + +The script downloads assets, normalizes filenames, and rewrites +references in `index.html` to relative paths (`fonts/foo.woff2`, +`images/hero.jpg`). Phase 3 transforms these depending on context: + +- **Template / fragment / CSS**: root-relative paths (`/fonts/...`, + `/images/...`). Browser resolves against code-bus host. +- **DA cell image refs**: relative paths (`images/hero.jpg`). The + calling pipeline's `rewriteImageRefs` rewrites these to DA Media + Bus URLs before pushing to DA. Do NOT use absolute branch URLs — + they break the pipeline's pattern matching. + +The `da-media-upload.mjs` script (Phase 5) uploads `da-media` assets +to DA and emits final `content.da.live` URLs; DA cells should be +updated to those final URLs after upload. + +| Aspect | absolute | vendor | da-media | +|---|---|---|---| +| Asset types | any | fonts only | images, videos | +| Repo size | unchanged | +font files (small) | unchanged | +| DA-cell URL form | source host (leave as-is) | N/A (fonts are in CSS, not DA cells) | relative (`images/...`) → pipeline rewrites | +| Delivered image URL | `./media_` (sideload) | `./media_` | `./media_` | This applies to template HTML, fragment HTML, DA cell values referencing images, and any CSS `url()` references. @@ -203,15 +204,15 @@ or consequences that aren't in `da-content`: page styling hooks to CSS-on-structure (`:has()`, sibling selectors) or swap to a preserved semantic element before emitting. -3. **`` URLs in DA cells are stricter than template/fragment - HTML.** DA cells require absolute URLs (`da-content` §9). - Template and fragment HTML can use root-relative `/assets/...` - because the browser resolves those against the rendered page host - (= code-bus host). The DA pipeline is what's stricter, not the - browser. Acceptable absolute forms in Snowflake DA cells: - - Public source page: `https:////image.png` - - Vendored same-branch assets: `https://----.aem.page/assets/...` - - DA media: `https://content.da.live///media_...` +3. **`` URLs in DA cells must be relative, not absolute.** + Phase 3 writes relative paths (`images/hero.jpg`) in DA cell + image refs. The calling pipeline's `rewriteImageRefs` matches + these patterns and rewrites them to DA Media Bus URLs before + the DA push. Absolute branch URLs + (`https://--...aem.page/images/...`) break the + pipeline's pattern matching. Template and fragment HTML use + root-relative paths (`/images/...`) instead — the browser + resolves those against the code-bus host. ### Slot rules in the template @@ -335,19 +336,16 @@ animations to settle, then capture. Save each as cannot reach the source's assets. Three options, in order of preference: -1. **Vendor the referenced assets under `/assets/` in the repo.** - Same paths work locally and on production via code-bus. Same-origin - so no CORS issues for fonts. Trade-off is repo size. Mechanical - steps: - - `cp -R ./assets/` - - Remove `.DS_Store`s and unreferenced files - - Rename any directory containing spaces (AEM CLI 404s on - URL-encoded `%20`) - - In template/fragments/CSS: rewrite localhost URLs to - root-relative `/assets/...` - - In DA doc cells: rewrite localhost URLs to ABSOLUTE branch URLs - (`https://----.aem.page/assets/...`) — Media - Bus requires absolute (see Generate phase rule #4). +1. **Deploy assets to the repo** (`fonts/`, `images/`, `videos/`). + `asset-collect.mjs` handles this automatically — it downloads, + normalizes, and rewrites refs in Phase 1. Wire (Phase 4) copies + them to repo root. Same paths work locally and on production via + code-bus. Same-origin so no CORS issues for fonts. Mechanical + rules: + - In template/fragments/CSS: root-relative `/fonts/...`, + `/images/...` + - In DA doc cells: relative paths (`images/...`) — the pipeline + rewrites these to DA Media Bus URLs before the DA push. 2. **Migrate assets to DA `/media/`.** Cleaner long-term; requires tooling not yet in scope. 3. **Skip production round-trip.** Lowest effort; ask the user first diff --git a/plugins/aem/edge-delivery-services/skills/snowflake/phases/1-capture.md b/plugins/aem/edge-delivery-services/skills/snowflake/phases/1-capture.md index b5d73cca..81d76972 100644 --- a/plugins/aem/edge-delivery-services/skills/snowflake/phases/1-capture.md +++ b/plugins/aem/edge-delivery-services/skills/snowflake/phases/1-capture.md @@ -101,45 +101,36 @@ curl -fsS "$SOURCE_URL" -o "${PROJ}/input/index.html" Validate: file size > 0, response was HTML (look for `` — external CSS -- `