Skip to content

Repository files navigation

zipo-frontend

Browser-based image compression — SSG, i18n, programmatic landing pages & SEO. Built with Vite + React + Tailwind CSS. Deployed on Cloudflare Pages.

Live demo: https://zipo.pics


✨ Features

  • SSG (Static Site Generation) — Vite + prerender.mjs renders every page to static HTML at build time. Zero server runtime, zero latency.
  • 9-Language i18n — Self-built lightweight i18n using useSyncExternalStore + localStorage. Supports RTL (Farsi), falls back to English. Languages: zh, zh-Hant, en, tr, fr, es, ko, ja, fa.
  • Programmatic Landing Pages — Define pages as slug tuples; auto-generate routes, sitemap, and hreflang. 55+ pages from a single data structure.
  • SEO Built-in — Per-page <title>, <meta description>, canonical URLs, hreflang alternates, sitemap.xml, robots.txt, llms.txt.
  • Cloudflare Pages — One-command deploy. Static assets served from edge, zero configuration.
  • Zero Dependencies on Server — No database, no backend API, no secrets. 100% client-side.

🚀 Quick Start

# Install
npm install

# Dev server (http://localhost:4174)
npm run dev

# Build (SSG → dist/)
npm run build

# Preview production build
npm run preview

🏗️ Architecture

src/
├── main.tsx              # Client entry (hydration)
├── App.tsx               # Root component (routes by locale+page)
├── entry-server.tsx      # SSR entry — renders React to HTML string
├── i18n/
│   └── index.tsx         # i18n provider + useSyncExternalStore
└── ...
prerender.mjs             # SSG pipeline — renders all (locale, page) combos
scripts/
├── gen-pages.mjs         # Generate programmatic landing page slugs
└── indexnow-push.mjs     # IndexNow URL submission (Bing/Yandex/Naver)
public/
├── robots.txt
├── _headers              # Cloudflare Pages headers (COI/COEP/CORP)
└── sitemap.xml           # Generated by prerender

How SSG Works

  1. vite builddist/index.html (template with <div id="app">)
  2. vite build --ssrdist-server/entry-server.js (SSR renderer)
  3. prerender.mjs iterates all (locale, page) targets → calls render() → writes dist/<locale>/<page>/index.html
  4. Generates sitemap.xml with hreflang alternates + robots.txt

Programmatic Landing Pages

// src/entry-server.tsx
const PAGES = {
  'compress-image-to': ['20kb', '50kb', '100kb', '200kb', '500kb'],
  'compress-image-for': ['twitter', 'instagram', 'linkedin', 'wordpress', 'web'],
}

// 9 languages × (1 home + 10 pages) = 99 static pages

Each page gets its own canonical URL, hreflang alternates in all 9 languages, and is included in the sitemap.

i18n

// Top-level keys must exist in ALL language files, or TypeScript fails.
// This is a design choice — it prevents missing translations at runtime.

const { t } = useI18n()
t('home.title')  // → "Free Image Compressor" (en) / "在线图片压缩工具" (zh)

☁️ Deploy to Cloudflare Pages

# 1. Build
npm run build

# 2. Deploy
npx wrangler pages deploy dist --project-name your-project

Or connect the repo in the Cloudflare Dashboard → Workers & Pages → Create → Pages → Connect to Git.

🔧 Tech Stack

Layer Technology
Framework Vite 6 + React 18
Styling Tailwind CSS 3
i18n Self-built (useSyncExternalStore + localStorage)
SSG vite build + prerender.mjs
Deploy Cloudflare Pages (edge, zero config)
TypeScript 5.6 (strict mode)

📄 License

MIT © 2026 zipo.pics contributors


zipo.pics — Free browser-based image compression
zipo.pics · Sitemap · Robots

About

Browser-based image compression frontend architecture - SSG, i18n, programmatic landing pages, SEO

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages