# Approaches for Handling Layered Images in Website Cloning Tasks: Detection and Implementation

> Learn to clone layered images by detecting img tags and CSS background-image values for pixel-perfect website cloning. Preserve visual fidelity with expert techniques.

- Repository: [JCodesMore/ai-website-cloner-template](https://github.com/JCodesMore/ai-website-cloner-template)
- Tags: how-to-guide
- Published: 2026-06-28

---

**Layered images in website cloning require detecting both `<img>` tags and CSS `background-image` values across the entire DOM tree to preserve pixel-perfect visual fidelity.**

When cloning a website using the `JCodesMore/ai-website-cloner-template` repository, a single visual element often comprises multiple stacked image layers—background gradients, foreground mockups, and overlay icons. Missing any layer results in a clone that looks incomplete or visually inaccurate, making proper handling of these assets essential for high-fidelity replication.

## Why Layered Assets Matter in Website Cloning

Visual components such as hero sections, cards, and modals are rarely single images. Instead, they are **compositions** assembled from several stacked layers, each with distinct positioning and z-index values.

- **Visual fidelity** – Overlays, gradients, and decorative icons contribute to the design’s visual weight. Omitting any layer breaks the pixel-perfect match.
- **Component composition** – UI elements often use `position: absolute` and `z-index` stacking contexts that depend on all layers being present.
- **AI generation pitfalls** – Automated agents that scrape only the top-most image generate components with blank spaces where overlays should appear.

According to the source code in [`.opencode/commands/clone-website.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/.opencode/commands/clone-website.md) (lines 55-56), the authors explicitly warn: *"Layered assets matter. A section that looks like one image is often multiple layers — a background watercolor/gradient, a foreground UI mockup PNG, an overlay icon. Inspect each container's full DOM tree and enumerate ALL `<img>` elements and background images within it, including absolutely-positioned overlays."*

## Detecting Layered Images in the DOM

### Traversing the Full DOM Tree

To capture every visual layer, you must inspect the complete DOM structure of each container:

1. **Walk container trees** – Examine every section, component wrapper, and grouping element.
2. **Collect `<img>` tags** – Record `src`, `alt`, dimensions, and computed CSS properties including `position` and `z-index`.
3. **Capture CSS backgrounds** – Use `getComputedStyle(element).backgroundImage` to detect decorative layers not implemented as `<img>` tags.
4. **Record context** – Store parent class names and sibling counts to identify overlay patterns and stacking order.

### The Asset Discovery Script

The repository provides a JavaScript snippet that runs inside a browser MCP (such as Playwright or Chrome DevTools) during the **Asset Discovery** phase. This script extracts all image layers, videos, background images, and fonts:

```javascript
// Run this via browser MCP to discover all assets
JSON.stringify({
  images: [...document.querySelectorAll('img')].map(img => ({
    src: img.src || img.currentSrc,
    alt: img.alt,
    width: img.naturalWidth,
    height: img.naturalHeight,
    // Include parent info to detect layered compositions
    parentClasses: img.parentElement?.className,
    siblings: img.parentElement ? [...img.parentElement.querySelectorAll('img')].length : 0,
    position: getComputedStyle(img).position,
    zIndex: getComputedStyle(img).zIndex
  })),
  videos: [...document.querySelectorAll('video')].map(v => ({
    src: v.src || v.querySelector('source')?.src,
    poster: v.poster,
    autoplay: v.autoplay,
    loop: v.loop,
    muted: v.muted
  })),
  backgroundImages: [...document.querySelectorAll('*')].filter(el => {
    const bg = getComputedStyle(el).backgroundImage;
    return bg && bg !== 'none';
  }).map(el => ({
    url: getComputedStyle(el).backgroundImage,
    element: el.tagName + '.' + el.className?.split(' ')[0]
  })),
  svgCount: document.querySelectorAll('svg').length,
  fonts: [...new Set([...document.querySelectorAll('*')].slice(0,200).map(el => getComputedStyle(el).fontFamily))],
  favicons: [...document.querySelectorAll('link[rel*="icon"]')].map(l => ({ href: l.href, sizes: l.sizes?.toString() }))
});

```

This code is referenced in [`.opencode/commands/clone-website.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/.opencode/commands/clone-website.md) at lines 94-102.

## Downloading and Organizing Image Layers

After the discovery script returns a JSON payload, the workflow delegates to a Node.js utility for retrieval:

```bash
node scripts/download-assets.mjs \
  --images assets.json \
  --output public/images

```

The `scripts/download-assets.mjs` utility (referenced in the workflow documentation) should implement three critical behaviors:

- **Parallelize** downloads using 4-6 concurrent requests to minimize latency.
- **De-duplicate** identical URLs to prevent redundant files.
- **Preserve naming context** – When two layers share filenames but belong to different components, prefix filenames with the component name (e.g., `hero-bg.webp`, `hero-overlay.png`).

Downloaded assets are stored in `public/images/` for static serving in Next.js.

## Implementing Layered Assets in Components

When reconstructing a component, import each layer as a separate asset and restore the original stacking context using CSS positioning.

For a hero section with three layers (background, mockup, overlay):

```tsx
import Image from 'next/image';
import heroBg from '@/public/images/hero-bg.webp';
import heroMockup from '@/public/images/hero-mockup.png';
import heroOverlay from '@/public/images/hero-overlay.svg';

export function HeroSection() {
  return (
    <section className="relative overflow-hidden">
      {/* Background layer */}
      <Image src={heroBg} alt="Background watercolor" fill className="object-cover" />
      {/* Foreground mockup */}
      <Image src={heroMockup} alt="UI mockup" width={1200} height={800} className="absolute inset-0 m-auto" />
      {/* Overlay icon */}
      <Image src={heroOverlay} alt="Decorative icon" width={80} height={80} className="absolute top-4 right-4" />
    </section>
  );
}

```

For SVG overlays, convert them to React components using the [`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx) utility:

```tsx
import { HeroOverlayIcon } from '@/components/icons';

export function HeroSection() {
  return (
    <section className="relative">
      <Image src={heroBg} alt="Background" fill />
      <Image src={heroMockup} alt="Mockup" className="absolute inset-0" />
      <HeroOverlayIcon className="absolute top-4 right-4 w-20 h-20" />
    </section>
  );
}

```

## Validation Checklist

During the **Pre‑Dispatch Checklist** (items 41-42 in [`.opencode/commands/clone-website.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/.opencode/commands/clone-website.md)), confirm that every layer has been captured:

- ✅ All `<img>` tags inside a container are listed in the discovery output.
- ✅ All CSS `background-image` values are enumerated.
- ✅ Parent class names and `z-index` values are recorded to reconstruct overlay order.
- ✅ Downloaded assets reside in `public/` and are correctly referenced in component code.

## Key Files for Layered Image Handling

| File | Purpose |
|------|---------|
| [`.opencode/commands/clone-website.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/.opencode/commands/clone-website.md) | Contains authoritative guidance on layered assets and the discovery script (lines 55-56, 94-102). |
| `scripts/download-assets.mjs` | Node.js utility for fetching and organizing discovered assets. |
| [`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx) | Destination for extracted SVG icons that form part of layered compositions. |
| `public/images/` | Storage directory for all downloaded image layers. |
| [`src/app/layout.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/layout.tsx) & [`src/app/globals.css`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/app/globals.css) | May define global background-image layers requiring duplication. |

## Summary

- **Layered images** are composite visual elements built from multiple stacked sources requiring complete enumeration.
- **Detection** requires traversing the full DOM to capture both `<img>` tags and CSS `background-image` values, including absolutely-positioned overlays.
- **Organization** depends on parallel downloading, URL de-duplication, and contextual naming to preserve component relationships.
- **Implementation** restores original stacking contexts using Next.js Image components with `position: absolute` and `z-index` properties.
- **Validation** against the Pre-Dispatch Checklist ensures no visual layers are omitted before deployment.

## Frequently Asked Questions

### How do I detect CSS background images that are not `<img>` tags?

Use `getComputedStyle(element).backgroundImage` on every element in the DOM tree. The provided discovery script filters for values that are not `'none'` and captures the URL along with the element identifier. This catches decorative gradients and patterns that traditional HTML scrapers miss.

### What is the best way to handle naming conflicts when downloading multiple layers?

Prefix each filename with its parent component or container name (e.g., `card-bg.jpg`, `card-icon.svg`). The `download-assets.mjs` script should reference the `parentClasses` field from the discovery JSON to generate these contextual prefixes, preventing identical filenames from different components from overwriting each other.

### Should I convert SVG overlays to React components or use them as image files?

Convert SVG overlays to React components using the [`src/components/icons.tsx`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/src/components/icons.tsx) utility. This approach allows dynamic styling via props (color, size) and ensures the overlay renders crisply at any resolution. Use the `<Image>` component for SVGs only when you need Next.js optimization features and the SVG is purely decorative.

### Why does my cloned component look empty even though I downloaded the main image?

You likely missed an absolutely-positioned overlay or a CSS background layer. Check the `position` and `z-index` values in the discovery output. Components often use transparent PNGs or SVGs positioned over background gradients—if the foreground layer is missing, the background appears blank or incomplete. Verify checklist items 41-42 in the clone command documentation to ensure all layers are enumerated.