How to Extract Design Tokens Using getComputedStyle() in the AI Website Cloner
The AI Website Cloner extracts design tokens by executing window.getComputedStyle() on representative DOM elements in a headless browser to capture the final computed values for fonts and colors.
The JCodesMore/ai-website-cloner-template repository automates website replication by analyzing target sites during the Foundation phase. Rather than parsing raw CSS files, the cloner uses a headless Chrome browser via Playwright to inspect the actual rendered styles. This approach ensures that the extracted design tokens reflect the precise visual appearance after all cascades, media queries, and CSS variable resolutions have been applied.
The Foundation Phase: Browser-Based Token Extraction
During the initial cloning workflow defined in .windsurf/workflows/clone-website.md, the system launches a headless browser context to inspect the target website's live DOM. This method captures the computed styles—the final values the browser actually renders—rather than the theoretical stylesheet values.
Selecting Representative Elements
The extraction script limits its scope to the first 200 elements to maintain performance while ensuring a representative sample. It targets a diverse set of node types including headings, paragraphs, links, and buttons using the following selector pattern:
const elements = [...document.querySelectorAll('*')].slice(0, 200);
This sampling strategy balances thoroughness with execution speed, preventing the script from processing thousands of unnecessary DOM nodes while still capturing the site's typographic and color palette diversity.
Executing getComputedStyle()
For each selected element, the cloner calls window.getComputedStyle(), which returns a live CSSStyleDeclaration object containing all active CSS properties. This is critical because it resolves inherited values, CSS custom properties (variables), and cascading rules into actual pixel values and color codes.
elements.forEach(el => {
const styles = getComputedStyle(el);
// styles.fontFamily, styles.color, etc. contain the final computed values
});
Extracting Font Tokens
Font extraction focuses on four key properties to fully characterize the typography: fontFamily, fontWeight, fontStyle, and fontSize. The cloner specifically targets text-bearing elements to build a comprehensive font stack inventory.
According to the workflow documentation in .windsurf/workflows/clone-website.md (lines 129–224), the extraction logic uses a Set to immediately de-duplicate values:
const fonts = [
...new Set(
[...document.querySelectorAll('*')].slice(0, 200)
.map(el => getComputedStyle(el).fontFamily)
)
];
This pattern ensures that if a site uses "Roboto" across 50 different elements, the token list contains only one entry, creating a clean design system specification.
Extracting Color Tokens
Color extraction follows a similar pattern but harvests multiple color properties to capture the complete palette. The system reads color (text), backgroundColor, and borderColor to identify primary, secondary, and accent colors used throughout the interface.
As documented in the workflow files (lines 246–250), the extraction targets these specific properties:
const colors = new Set();
const elements = [...document.querySelectorAll('*')].slice(0, 200);
elements.forEach(el => {
const cs = getComputedStyle(el);
colors.add(cs.color);
colors.add(cs.backgroundColor);
colors.add(cs.borderColor);
});
return [...colors];
Because getComputedStyle() returns colors in standardized RGB or hexadecimal notation (e.g., rgb(26, 115, 232) or #1a73e8), the cloner receives consistent, parseable values regardless of whether the original CSS used hex codes, HSL functions, or CSS variables.
De-duplication and Token Generation
After extraction, the cloner processes the raw values to create a normalized design token file. The de-duplication occurs during the collection phase using JavaScript's Set object, as shown in the examples above. This prevents redundant entries and creates a concise design system.
The extracted tokens are then transformed into CSS custom properties and stored in src/app/globals.css:
@layer base {
:root {
--font-primary: 'Roboto', sans-serif;
--color-primary: #1a73e8;
--color-background: #ffffff;
}
}
These values originate directly from the getComputedStyle() output captured during the browser inspection phase.
Injecting Tokens into the Next.js Application
The final step integrates the extracted fonts into the Next.js application structure. The cloner modifies src/app/layout.tsx to import the discovered fonts via next/font/google or next/font/local, depending on whether the detected typefaces are Google Fonts or local files.
As noted in the README (lines 92–94), the system populates the layout file with the actual font families discovered during the extraction:
import { Inter } from 'next/font/google';
const customFont = Inter({
subsets: ['latin'],
variable: '--font-primary'
});
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en" className={customFont.className}>
<body>{children}</body>
</html>
);
}
This injection ensures that the cloned website uses the exact same typography as the original, loaded optimally through Next.js's font optimization system.
Summary
- The AI Website Cloner uses
getComputedStyle()in a headless Playwright browser to capture final computed values rather than parsing raw CSS files. - The extraction samples up to 200 DOM elements to balance thoroughness with performance.
- Font tokens are extracted from
fontFamily,fontWeight, andfontStyleproperties, while color tokens come fromcolor,backgroundColor, andborderColor. - JavaScript
Setobjects de-duplicate values during collection to create clean design system specifications. - Extracted tokens populate
src/app/globals.cssas CSS variables andsrc/app/layout.tsxvianext/fontintegrations. - The workflow is defined in
.windsurf/workflows/clone-website.mdand documented in the README (lines 96–98).
Frequently Asked Questions
What is getComputedStyle() and why is it used for design token extraction?
getComputedStyle() is a browser API that returns the final computed values of all CSS properties for a given element after applying stylesheets, inline styles, and inheritance. The AI Website Cloner uses this method because it resolves CSS variables, media queries, and complex selectors into actual usable values (like #1a73e8 instead of var(--primary-color)). This ensures the extracted design tokens match the exact visual appearance of the target site.
How does the AI Website Cloner handle CSS custom properties and variables?
The cloner handles CSS custom properties indirectly by reading the computed values rather than the variable definitions. When getComputedStyle() returns a color value, it has already resolved any var(--color-primary) references into actual hex or RGB values. This means the cloner captures the effective design system as rendered, not the abstract variable structure, which is preferable for creating a pixel-perfect replica.
Which files are modified during the design token extraction process?
The primary files modified are src/app/globals.css (receiving CSS custom properties for colors and spacing) and src/app/layout.tsx (receiving next/font imports for typography). The extraction logic itself resides in .windsurf/workflows/clone-website.md, which defines the JavaScript evaluation scripts run in the headless browser context.
Why limit the element selection to 200 nodes?
The 200-element limit (slice(0, 200)) prevents performance degradation during the cloning process while still capturing the site's dominant design patterns. According to the source code in .windsurf/workflows/clone-website.md, this threshold provides a representative sample of the site's typography and color usage without the overhead of processing thousands of DOM nodes, particularly important for large single-page applications.
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 →