Inspiration

What it does

AI-based Desktop Setup Builder

Inspiration

I've spent way too many hours scrolling Reddit's r/battlestations and YouTube setup tours, saving screenshots of monitors, chairs, and keyboards I wanted — then losing track of everything across browser tabs and notes apps. There was no good way to visualize a complete setup before buying it. I wanted something where you could point at a spot on a virtual desk and say "put a white mechanical keyboard here" — and it just works.

The idea clicked when I realized AI could bridge the gap between a vague description and a specific real product. Instead of browsing endlessly, you describe what you want and the AI figures out the exact model.


What I Learned

  • How to use Gemini's structured JSON schema output to get reliable, parseable product data instead of free-form text
  • How Google Custom Search API with searchType=image works for fetching real product photos programmatically
  • The reality of browser CORS restrictions — calling external APIs from a local file:// page is blocked by default, which pushed me toward understanding how to properly serve and deploy static apps
  • Why API keys should never be hardcoded in frontend code, and how to use a config.js + .gitignore pattern to keep secrets off GitHub
  • How to structure a multi-step AI pipeline: identify product → fetch image → render in UI, with live status indicators at each step

How I Built It

The entire app is a single HTML file with no frameworks or build tools — just vanilla JavaScript, CSS, and two external APIs.

The pipeline for each slot:

$$\text{User prompt} \xrightarrow{\text{Gemini 2.5 Flash}} \text{Product JSON} \xrightarrow{\text{Google Image Search}} \text{Real photo} \xrightarrow{\text{DOM render}} \text{Slot filled}$$

  1. Room scene — built with pure CSS: a wall, desk surface with perspective clip-path, floor, and legs. Every component slot is an absolutely positioned circle at coordinates that match where that item physically lives in a real setup.

  2. Gemini integration — each slot click sends a structured prompt to Gemini 2.5 Flash with a strict JSON response schema, returning name, brand, price, emoji, and a one-line description. The schema enforcement means zero parsing failures.

  3. Google Image Search — the returned product name and brand become a search query to Google Custom Search API with searchType=image, fetching up to 10 candidates and picking the first one that actually loads.

  4. AI Full Build — one prompt fills all 15 slots simultaneously. Gemini returns an array of components in a single call, then images are fetched slot by slot with a live progress overlay.

  5. Setup Rating — after building, Gemini scores the setup across aesthetics, performance, value, and ergonomics using a structured rating schema, with animated bar charts rendered from the response.


Challenges

CORS was the biggest wall. Browsers block API calls from file:// origins to external APIs — this caused hours of "Failed to fetch" errors before I understood that the solution was simply serving the file over http://localhost instead of opening it directly.

Getting Google image search to actually work took several iterations. The first approach used a regular web search and tried scraping pagemap.cse_image from page metadata — unreliable and often empty. Switching to searchType=image was the correct fix, returning actual image URLs directly.

Keeping API keys out of GitHub became a real problem when GitHub's push protection blocked the first commit for containing a live GCP API key. This forced me to properly separate configuration into a config.js file excluded via .gitignore — a better practice anyway.

Gemini's array schema for the full build feature required careful prompt engineering. Getting it to return exactly the right slotId values mapped to real products consistently took several iterations of the system prompt.

How we built it

Challenges we ran into

Accomplishments that we're proud of

What we learned

What's next for AI-based Desktop Setup Builder

Built With

Share this project:

Updates