How the AI Website Cloner Extracts Font Information: Runtime Detection and Next.js Integration
The system extracts font information through a two-phase pipeline that captures computed font families from the target page's DOM and integrates them into the Next.js application using next/font/google helpers and CSS custom properties.
The JCodesMore/ai-website-cloner-template automates website replication by building a comprehensive foundation of design tokens. Extracting font information is a critical step in this process, ensuring the cloned site maintains typographic fidelity with the original. The system coordinates between runtime browser inspection and static build configuration to detect and implement fonts correctly.
Phase 1: Runtime Font Detection in the Browser
The first phase occurs when builder agents load the target page in a headless browser. According to the source code in .windsurf/workflows/clone-website.md (line 219) and .github/skills/clone-website/SKILL.md (line 222), the system executes a JavaScript snippet that samples DOM elements to extract computed font families.
The script enumerates fonts by querying the first 200 elements to balance performance with coverage:
const fonts = [
...new Set(
[...document.querySelectorAll('*')]
.slice(0, 200) // sample a subset of elements
.map(el => getComputedStyle(el).fontFamily)
)
];
This approach captures every distinct fontFamily value rendered by the browser, including Google Fonts, self-hosted typefaces, and system fallbacks. The resulting array is written to the project's research artifacts and passed to the build step for integration.
Phase 2: Static Integration with Next.js
Once the font families are identified, the system integrates them into the Next.js application through two key files: src/app/layout.tsx and src/app/globals.css.
Registering Fonts in the Layout
The layout component uses next/font/google to import and optimize the detected fonts. As implemented in src/app/layout.tsx, the system creates CSS variables for each font:
import { Geist, Geist_Mono } from "next/font/google";
const geistSans = Geist({ subsets: ["latin"], variable: "--font-geist-sans" });
const geistMono = Geist_Mono({ subsets: ["latin"], variable: "--font-geist-mono" });
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" className={`${geistSans.variable} ${geistMono.variable}`}>
<body>{children}</body>
</html>
);
}
Configuring Global Styles
The global stylesheet in src/app/globals.css maps these variables to the application's typographic defaults:
:root {
--font-sans: "Geist", "Geist Fallback", ui-sans-serif, system-ui, sans-serif;
--font-mono: "Geist Mono", "Geist Mono Fallback", ui-monospace, monospace;
}
body {
@apply font-sans;
}
This architecture exposes fonts as CSS custom properties, making them globally available to all components while maintaining Next.js optimization benefits.
Research and Validation
The docs/research/INSPECTION_GUIDE.md file formalizes the font extraction process by listing "Typography" as a required inspection task. This guide ensures agents capture not only font families but also weights, line-heights, and spacing before generating the foundation files.
Practical Implementation Examples
When adding a newly discovered Google Font to the cloned project, the system extends the layout configuration:
import { Inter } from "next/font/google";
const inter = Inter({ subsets: ["latin"], variable: "--font-inter" });
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html
lang="en"
className={`${inter.variable} ${geistSans.variable} ${geistMono.variable}`}
>
<body>{children}</body>
</html>
);
}
Components then reference these variables directly:
export function Heading({ children }: { children: React.ReactNode }) {
return (
<h1 className="font-[var(--font-inter)] text-3xl">
{children}
</h1>
);
}
Summary
- Runtime Detection: The system executes a JavaScript snippet in a headless browser (defined in
.windsurf/workflows/clone-website.mdand.github/skills/clone-website/SKILL.md) to sample 200 DOM elements and extract computed font families. - Next.js Integration: Extracted fonts are registered in
src/app/layout.tsxusingnext/font/googleand exposed as CSS custom properties. - Global Availability: The
src/app/globals.cssfile maps variables to font stacks, ensuring consistent typography across the application. - Research Compliance: The
docs/research/INSPECTION_GUIDE.mdmandates typography inspection to validate font extraction accuracy.
Frequently Asked Questions
How does the system handle Google Fonts specifically?
The system detects Google Fonts during runtime inspection when they appear as computed font families in the DOM. During integration, these fonts are imported via next/font/google in src/app/layout.tsx, which provides automatic optimization, subsetting, and variable font support without requiring manual <link> tag injection.
Why is the DOM sampling limited to 200 elements?
The script limits sampling to 200 elements (slice(0, 200)) to maintain performance during the cloning workflow. This threshold provides sufficient coverage to identify the primary font families used across the site while preventing excessive computation time on large DOM trees.
Can the system extract local or self-hosted fonts?
Yes, the runtime inspection captures any font family name returned by getComputedStyle(), including self-hosted fonts and system fallbacks. However, for local fonts not available through next/font/google, the system requires manual configuration in src/app/layout.tsx using next/font/local with the appropriate file paths.
Where are the extracted fonts stored before integration?
The font data extracted during runtime is written to the project's research artifacts as part of the design foundation. These values are then consumed by the build process to generate the appropriate imports in src/app/layout.tsx and variable definitions in src/app/globals.css.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →