How to Organize and Reference Assets from Target Sites Using ai-website-cloner-template

The ai-website-cloner-template stores all downloaded assets in the public/ folder while preserving the original directory structure from the target site, enabling reference via absolute paths in Next.js components.

The ai-website-cloner-template repository provides a systematic approach to handling media files extracted during website cloning. When replicating a target site, managing images, videos, fonts, and icons requires strict organization to ensure components render correctly. This guide explains how the template structures asset storage and the exact methods for referencing those files in your generated Next.js application.

Asset Storage Conventions in public/

The template follows a strict convention for binary files extracted from target websites. Every asset routes to a specific subdirectory under public/, leveraging Next.js static file serving capabilities.

The Standard Folder Structure

According to the README's Foundation step at [README.md‑L94](https://github.com/JCodesMore/ai-website-cloner-template/blob/master/README.md#L91), the template organizes assets into three primary directories:

  • public/images/ – Raster images including PNG, JPG, and WebP files
  • public/videos/ – Video assets such as MP4 and WebM formats
  • public/seo/ – Favicons, Open Graph images, and manifest files

Preserving Source Hierarchy

When the cloning skill executes, the scripts/download-assets.mjs helper preserves the original directory structure from the target URL. A logo located at https://example.com/assets/logo.svg maps directly to public/images/assets/logo.svg in your local project. This mirroring simplifies traceability when auditing or replacing specific assets.

The workflow description detailing this behavior appears in the platform-specific skill files, specifically the Windsurf workflow at [.windsurf/workflows/clone-website.md‑L190](https://github.com/JCodesMore/ai-website-cloner-template/blob/master/.windsurf/workflows/clone-website.md#L183).

Downloading Assets from Target Sites

The asset acquisition process uses a Node.js script that walks the DOM, collects resource URLs, and streams files to the appropriate public/ subdirectories.

The download-assets.mjs Script

The script identifies every <img> tag, CSS background-image URL, and <video> source, then writes files while maintaining subdirectory depth. Below is the core logic for saving remote assets:

// scripts/download-assets.mjs
import { promises as fs } from "fs";
import path from "path";
import fetch from "node-fetch";

/**
 * Save a remote file to the public folder while preserving its original path.
 */
async function saveAsset(url: string, root = "public") {
  const { pathname } = new URL(url);
  // Remove leading slash and prepend the appropriate public sub-folder
  const relative = pathname.replace(/^\/+/, "");
  const dest = path.join(root, "images", relative); // assumes image; adjust for videos

  await fs.mkdir(path.dirname(dest), { recursive: true });
  const res = await fetch(url);
  if (!res.ok) throw new Error(`Failed to fetch ${url}`);
  const buffer = await res.buffer();
  await fs.writeFile(dest, buffer);
  console.log(`✓ saved ${url} → ${dest}`);
}

// Example usage – called for each discovered asset URL
await saveAsset("https://example.com/assets/logo.png");

Supported Asset Types

The template handles multiple binary formats during the cloning process:

  • Images: PNG, JPG, WebP, SVG (raster), and GIF files route to public/images/
  • Videos: MP4, WebM, and MOV files populate public/videos/
  • SEO Assets: Favicons, Apple touch icons, and Open Graph images land in public/seo/

Referencing Assets in Next.js Code

Because all assets reside under public/, you reference them using absolute URL paths starting with a slash. This eliminates the need for import statements and enables zero-runtime-code serving.

Using the Image Component

For raster images, employ the built-in <Image/> component to enable automatic optimization. The src attribute points to the absolute path inside public/:

import Image from "next/image";

export function Logo() {
  return (
    <Image
      src="/images/assets/logo.svg"   // ← path inside `public/`
      alt="Company logo"
      width={200}
      height={80}
      priority                 // optional: preload for above-the-fold assets
    />
  );
}

CSS Background Images

Reference downloaded images within CSS using standard url() syntax with absolute paths:

.hero {
  background-image: url("/images/hero/background.webp");
  background-size: cover;
}

Video and Media Files

For video assets stored in public/videos/, use the HTML5 <video> element with an absolute src path:

export function HeroVideo() {
  return (
    <video
      src="/videos/hero/intro.mp4"
      autoPlay
      muted
      loop
      className="w-full h-auto"
    />
  );
}

SEO Assets and Favicons

Reference favicons and Open Graph images in your layout or head component using the public/seo/ directory:

import Head from "next/head";

export default function SiteHead() {
  return (
    <Head>
      <link rel="icon" href="/seo/favicon.ico" />
      <meta property="og:image" content="/seo/og-image.png" />
    </Head>
  );
}

Handling SVG Icons

Individual SVG icons extracted from the target site undergo conversion into React components. The template gathers these in src/components/icons.tsx, where each component imports the SVG directly from public/images/ and re-exports it. This centralized approach allows consistent icon usage throughout the UI while maintaining the source file in the public directory.

Benefits of the Public Folder Strategy

Organizing assets under public/ provides specific advantages for cloned websites:

  • Zero Runtime Overhead: Next.js serves public/ files without bundling them into your JavaScript, reducing client-side payload
  • Structural Fidelity: Mirroring the source site's directory layout simplifies asset replacement and auditing
  • Exact Path Resolution: Builder agents receive precise file paths in component specifications, eliminating guesswork and ensuring pixel-perfect replication
  • SEO Preservation: Keeping favicons and OG images in public/seo/ maintains the original site's search engine optimization metadata

Summary

  • Store all cloned assets under public/ with subdirectories for images, videos, and seo files
  • The scripts/download-assets.mjs helper preserves the target site's original directory hierarchy during download
  • Reference assets using absolute paths starting with / rather than relative imports
  • Use Next.js <Image/> for raster graphics, absolute URLs for CSS backgrounds, and standard HTML tags for video content
  • SVG icons convert to React components in src/components/icons.tsx while their source files remain in public/images/

Frequently Asked Questions

Where does ai-website-cloner-template store downloaded images?

The template stores all raster images in public/images/, maintaining the subdirectory structure from the source website. For example, an image from https://example.com/assets/photo.jpg saves to public/images/assets/photo.jpg in your local project.

How do I reference a cloned video file in my component?

Reference video files using an absolute path pointing to the public/videos/ directory. Use the HTML5 <video> element with the src attribute set to /videos/ followed by the preserved subdirectory path, such as /videos/hero/intro.mp4.

What happens to SVG icons extracted from the target site?

The template converts extracted SVG icons into React components and collects them in src/components/icons.tsx. Each component references the original SVG file stored in public/images/, allowing you to import and use icons throughout your application while keeping source assets organized.

Why use absolute paths instead of imports for assets?

Absolute paths starting with / leverage Next.js static file serving from the public/ directory, eliminating the need for build-time imports. This approach reduces bundle size, preserves the original URL structure for SEO consistency, and allows builder agents to generate exact references without resolving relative import paths.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →