TechGeek.uz
A data-built storefront for smart glasses in Uzbekistan: 104 SKUs in Russian and Uzbek, prices in dollars or sum, checkout through Telegram.
- Variant configurator
- USD ↔ UZS at the central-bank rate
- Telegram-draft checkout
- RU / UZ technical SEO
- Discipline
- Commerce
- Year
- 2025–26
- Authorship
- Own build
- Status
- Role
- Sole developer and operator of the web channel: design, front end, catalogue pipeline, serverless API and SEO.
- Surfaces
- Web storefront · desktop and mobile
- Languages
- RU · UZ
- Stack
- HTML · CSS · Vanilla JavaScript · Node.js build scripts · Vercel Functions · GitHub Actions · JSON-LD · Google Merchant feed
Survey — context and problem.
The problem
A variant-heavy catalogue, prices buyers think of in sum, no payment back end — and a v1 that exposed a bot token in public code.
TechGeek.uz sells Ray-Ban Meta, Oakley Meta and Meta smart glasses, plus WHOOP bands, to buyers across Uzbekistan. Everything is ordered on request and sourced from abroad; a manager closes each order in Telegram or by phone, and delivery across the country is free.
The catalogue is the hard part. Smart glasses come in a large matrix of generations, frames, colours, lenses and sizes, and local buyers cannot order from Meta’s store directly. Prices must be credible and readable in sum, not only in dollars. Grey-market worries make trust essential. The store has no payment processor or order back end, and it needs to be found on both Google and Yandex, in Russian and in Uzbek.
The first version, a dark wholesale landing page from December 2025, also pushed orders to Telegram from client-side code — which meant a bot token sat in public JavaScript. The job was to turn it into a retail storefront that is fast, honest about availability and safe by design.
Plan — the system, drawn first.
The solution
A static storefront generated from sourced catalogue data: variant configurator, USD ↔ UZS at the central-bank rate, a Telegram-draft checkout and bilingual technical SEO.
Instead of typing products by hand, the storefront is generated. Public product data is collected from Meta’s store, normalised into 104 SKUs across 13 glasses families plus WHOOP, priced by a single rule and published by a deterministic build into model pages, homepage cards, the sitemap, structured data and a Google Merchant feed. A CI check fails the build if prices disagree anywhere. Each model gets a configurator that swaps image, price, SKU and URL state as colour, lens and size change. Prices switch between dollars and sum through a small Vercel function that proxies the Central Bank of Uzbekistan rate, caches it and returns an honest error rather than an invented number. The cart is local and tamper-proof, and checkout opens a pre-filled Telegram message — no bot token and no personal data in public code.
Module key
- Catalogue with category, line, generation and sort filters and a live results count
- Variant configurator on every card and model page, with URL state
- USD / UZS switch backed by the Central Bank rate, marked as indicative
- Persistent, tamper-proof cart drawer with cross-tab sync
- Pre-filled Telegram order draft in Russian or Uzbek
- 13 model pages in two languages, buyer’s guides and a real 404
- Structured data: Organization, ProductGroup, Offer, Breadcrumb, FAQ and Article
- Google Merchant feed, sitemap, llms.txt, Yandex and Bing verification
Key decisions
-
Why static HTML instead of a framework
A storefront like this is content that changes between builds, not between clicks. Prebuilt pages with no npm runtime dependencies load fast, index cleanly and leave very little to patch.
-
Why checkout is a Telegram draft, not a bot
The v1 bot needed a token in the browser. A pre-filled t.me message needs no secret at all, keeps the manager’s workflow, and is tracked as intent — never as a sale.
-
Why the catalogue is generated, not typed
One source file feeds pages, structured data, the sitemap and the Merchant feed, and CI compares prices across all of them. A price cannot be right on one page and wrong on another.
-
Why sum prices are marked indicative
The rate comes from the Central Bank of Uzbekistan and is cached for an hour. If it cannot be fetched, the site says so instead of guessing, and rates older than ten days are rejected.
-
Why availability says “on request”
Nothing is marked in stock until fulfilment is confirmed, and quote-only items never show a zero or a fixed total. Honest availability is cheaper than a broken promise.
Elevations — the desktop screens.
All elevations 03
-
Fig. 4.1 Catalogue section with category tabs, line, generation and sort selects, a USD / UZS currency switch and the first row of smart-glasses cards. -
Fig. 4.2 Electric-blue Ray-Ban Meta feature panel with a lime 12 MP camera callout and three numbered benefits. -
Fig. 4.3 Ray-Ban Meta Gen 1 vs Gen 2 buyer’s guide with a comparison table and “when to choose” cards.
Details — the mobile screens.
Every mobile screen 05
Materials schedule — the stack, and why.
| Layer | Material | Why |
|---|---|---|
| 01Data | catalog.json · 104 SKUs · sourced product JSON-LD | One normalised source feeds every page, schema block and feed. |
| 02Logic | Node.js build scripts · deterministic generator | Rebuilding the whole catalogue is one command, and CI checks prices end to end. |
| 03Intelligence | Codex agent: daily SEO routine with guardrails | Crawl, index and feed health checked every day, with cooldowns, no invented data and human approval for anything external. |
| 04Interface | Static HTML · CSS custom properties · vanilla JS · Manrope | Fast pages with no framework and self-hosted Cyrillic and Latin font subsets. |
| 05Infra | Vercel CDN · one Node function · GitHub Actions | Static hosting plus a single serverless proxy for the exchange rate; CI runs tests and site checks on every push. |
Stack
Completion — outcome and links.
Verified facts
- SKUs across 13 glasses families + WHOOP
- 104
- Source: site check, 29 Sep 2026
- indexable URLs, RU + UZ
- 44
- Source: sitemap, 29 Sep 2026
- npm runtime dependencies
- 0
- Source: from the repository, Sep 2026
- storefront languages
- RU · UZ
Want to see it running?
I can walk you through the live system on demo data and explain the decisions behind it.
Request a walkthrough




