完全静态的波斯语电商前端,无后端、无数据库,所有数据在浏览器端处理
TakMarket-public — Vite 电商模板
作者 lavaoverjava
一个使用 Vite + React 构建的完全静态波斯语电子产品商店模板,包含商品浏览、筛选、购物车和心愿单,所有数据在浏览器端处理,无后端。
看看你的网站会是什么样
浏览真实页面截图,比较内容排版与手机效果。点击下方缩略图切换,放大查看整页细节。
全部页面与视图 3
截图用于了解视觉与布局,交互效果请以实际项目为准。
值得关注的模板亮点
从已有项目资料中,快速了解它的特点。
内置 33 件商品和 8 个分类,支持全文搜索、多条件筛选、排序和分页
购物车与心愿单通过 localStorage 持久化,刷新后仍然保留
从右到左布局,使用 CSS 逻辑属性和波斯数字格式化,自托管 Vazirmatn 字体
构建时为 44 个可索引路由生成独立 HTML 文件,包含各自的元数据和 JSON-LD
包含演示用支持聊天窗口,使用关键词匹配的预设回复并明确说明无人值守
模板详细介绍
TakMarket-public 是一个面向波斯语(从右到左布局)的电子产品商店前端模板,基于 Vite 和 React 构建,并发布为纯静态站点。它内置 33 件商品、8 个分类,支持全文搜索、品牌/价格/库存/折扣/评分筛选、排序和分页,这些操作全部在浏览器中基于静态 JSON 数据完成,不调用任何 API。购物车和心愿单通过 Zustand 的 persist 中间件保存在 localStorage 中,刷新页面后仍然保留。
该模板在构建时为 44 个可索引路由生成独立的 HTML 文件,每个文件带有自己的标题、描述、canonical 标签、社交标签和 JSON-LD 结构化数据,同时生成 sitemap.xml 和社交分享卡片。由于没有后端,登录、注册、下单和订阅表单虽然具备完整的界面和校验,但提交时只会显示一条说明,告知当前构建没有后端,不会伪造成功状态。管理后台已被完全移除。
模板使用 TypeScript 严格模式、Tailwind CSS 和 Zod 表单校验,并包含可访问性支持(跳转链接、焦点管理、减少动画偏好等)。演示用的支持聊天窗口使用关键词匹配的预设回复,并明确说明没有真人在线。
适合你的项目吗?
适用场景
- 作为学习 Vite + React 静态电商前端结构的参考项目
- 用于演示无后端条件下如何实现商品浏览、筛选和购物车功能
- 作为波斯语或从右到左布局电商界面的起步模板
- 用于测试静态站点在 GitHub Pages 上的部署和预渲染方案
适合人群
- 希望研究纯前端电商实现方式的开发者
- 需要波斯语 RTL 电商界面模板的前端开发者
- 计划在 GitHub Pages 上托管静态演示商店的个人或团队
上手与定制指南
结合仓库当前版本的说明,按下面的资料检查内容、配置与运行要求。
- 1
运行 npm install 安装依赖,然后 npm run dev 启动开发服务器(默认端口 3000)
- 2
运行 npm run build 生成静态站点到 dist/ 目录,npm start 可本地预览构建结果
- 3
添加或编辑商品时,修改 src/data/products.json 并将 WebP 图片放入 public/,再运行 npm run build:images 生成缩略图
- 4
summaries.json 和 sitemap.xml 由脚本自动生成,不应手动编辑
- 5
登录、注册、下单和订阅功能在此静态构建中没有后端支持,提交时仅显示提示
授权与来源资料
使用条件与限制
免费使用 · 保留许可声明本次收录的是公开仓库中采用 MIT 许可的免费版本;免费范围为该版本代码,不代表外部服务或第三方素材免费。
使用时需要遵守
- 允许免费使用、修改、商用和分发该版本代码。
- 分发代码副本或实质性部分时,保留原作者版权声明和完整 MIT 许可声明。
- 代码按现状提供;担保与责任限制以原许可证及适用法律为准。
额外费用与待核对事项
- 模板中的电话、邮箱和地址均为占位符,用于真实商店前必须替换。
- 登录与注册页面仅有界面和校验,静态构建无后端,提交时只显示提示,不会真正登录。
- 结算下单表单无法真正提交订单,静态构建无后端,提交时仅显示提示。
- 订阅表单无后端支持,提交时仅显示提示,不会真正订阅。
- 管理后台已被完全移除,模板不包含任何后台管理功能。
- 在 GitHub Pages 上无法设置真实 HTTP 安全响应头,如需防点击劫持等需改用支持自定义头的托管服务。
- 本项目为他人开源模板的衍生作品,MIT 许可证中须保留原作者 Aleksandar Kuzmanović 的版权声明。
- 演示图片、字体、图标及其他第三方素材需按各自许可核对,不能仅凭代码的 MIT 许可判断。
- 域名、托管、数据库、支付或 AI 等外部服务可能另外收费。
查看原文依据
Permission is hereby granted, free of charge
许可证原文
The phone, email and address are deliberate placeholders — replace them before using this for a real shop.
README 原文
Login and register (`/login`, `/register`)
README 原文
Placing an order (`/checkout`)
README 原文
Newsletter signup
README 原文
The admin dashboard was dropped entirely
README 原文
Real HTTP security headers (`X-Frame-Options`, or `frame-ancestors` against clickjacking) can't be set on GitHub Pages
README 原文
https://github.com/lavaoverjava/TakMarket-public/blob/main/LICENSEhttps://github.com/lavaoverjava/TakMarket-public/blob/main/README.mdThis started life as a fork of an open-source storefront template by Aleksandar Kuzmanović; that copyright line stays in `LICENSE`
README 原文
DeepSeek 根据仓库许可证和 README 整理 ·2026-10-01。结果仅覆盖已读取资料,依赖、图片、字体及后续条款变更以各自原文为准。
项目核对记录与介绍依据
模板资料
- 来源平台
- GitHub
- 资料与维护参考分
- 资料较完整 · 85 / 100
- 技术栈
- Vite · React
- 网站类型
- 电商
这个分数如何计算
本站按许可资料(最高30分)、演示链接(12分)、预览图(10分)、Star数(15分)、记录的维护时间(15分)、描述完整度(8分)、功能记录(5分)和分类资料(5分)计算。它不是代码、安全或性能测试,也不是 Google 评分;有链接不代表已实测可用。
这个项目需要核对什么
- 记录的仓库更新时间
- 2026-08-14
- 截图检查日期
- 2026-10-01
已收录演示链接。请用你的内容与屏幕尺寸检查;有演示不代表表单、认证或支付已经可用。
目录记录的主要技术栈是 Vite。请通过依赖清单和锁文件核对实际版本与托管要求。这些说明基于收录资料,不代表代码审计或部署实测。
查看具体选型方法 →介绍的制作与核对状态
介绍由 AI 辅助整理目录与仓库资料。仓库作者不等于这篇介绍的审核者。
已完成服务器许可规则与 AI 来源核对;未经过人工编辑审核。
查看当时使用的来源资料
SHA-256: 11d17de444e0c7f47dcbe75597dddc88d22044654ef5792ac1dbfe35cbbd7595
2026-10-01T01:31:00.669Z
来源文件 / 仓库<div align="center">
<img src="public/apple-touch-icon.png" alt="TakMarket" width="120" height="120">
# 🛒 تکمارکت — TakMarket
**A fully static, right-to-left Persian electronics storefront, built with Vite + React and served from GitHub Pages.**
33 products · 8 categories · client-side search, filters and cart · no backend, no database, no tracking.
[**🛍️ Open the store**](https://lavaoverjava.github.io/TakMarket-public/) · [🐛 Report a bug](https://github.com/lavaoverjava/TakMarket-public/issues)
</div>
---
## 📑 Contents
- [✨ Features](#-features)
- [⚠️ What "no backend" means here](#️-what-no-backend-means-here)
- [🛠️ Tech stack](#️-tech-stack)
- [🚀 Installation and usage](#-installation-and-usage)
- [📂 Code structure](#-code-structure)
- [🖼️ Adding or editing products](#️-adding-or-editing-products)
- [⚡ Performance notes](#-performance-notes)
- [🛡️ Security notes](#️-security-notes)
- [🎨 Customization](#-customization)
- [📄 License](#-license)
---
## ✨ Features
**🔎 A real catalogue, searched in the browser.** 33 products across 8
categories, with full-text search, brand/price/stock/discount/rating filters,
sorting and pagination — all running on static JSON, no API call anywhere.
Every one of those choices lives in the query string, so a filtered view is a
URL you can bookmark, share, refresh, or step back out of.
**🧭 Right-to-left by design.** Persian throughout, laid out with CSS logical
properties (`start`/`end`, not `left`/`right`), Persian digit formatting for
every price and count, and the self-hosted **Vazirmatn** typeface.
**🛒 A cart and wishlist that survive a refresh.** Both live in `localStorage`
via Zustand's `persist`, and both treat what they read back as untrusted input
— corrupt or hand-edited entries are dropped or clamped rather than rendered.
**📱 Responsive from 320px up.** Mobile-first layout, a slide-in menu, a
scrollable category rail, and no horizontal overflow at any breakpoint.
**💬 Demo support chat.** A floating widget with a typing indicator and
keyword-matched canned replies. It says up front that nobody is on the other
end — see `src/lib/chatReplies.ts`.
**♿ Accessible.** Skip-to-content link, one `<h1>` per page, labelled form
fields and icon buttons, visible `:focus-visible` rings, drawers that really
trap focus instead of only claiming `aria-modal`, and a
`prefers-reduced-motion` block that turns the animations off.
**🔒 Hardened by default.** A restrictive `Content-Security-Policy` meta tag
ships in `<head>` — and the published build drops `'unsafe-inline'` from
`script-src` entirely. Forms are validated with Zod, and no component anywhere
uses `dangerouslySetInnerHTML`.
**🔗 Every URL is a real page.** All 44 indexable routes are written out as
their own HTML file at build time, each with its own title, description,
canonical tag, social tags and JSON-LD (`Product`, `BreadcrumbList`,
`Organization`), plus a matching `sitemap.xml` and a 1200×630 social card
drawn from the site's own logo and typeface.
---
## ⚠️ What "no backend" means here
GitHub Pages serves static files only — no Node process, no database. The
original project had an Express + MySQL backend; this build does not, and it
never pretends otherwise.
### Works completely ✅
| Area | Notes |
| --- | --- |
| Browsing and search | Runs on static JSON, in the browser |
| Filtering and sorting | Brand, max price, in-stock, discounted, rating |
| Pagination | Fully client-side |
| Product detail pages | Image gallery, spec table, related products |
| Cart | Saved in the visitor's `localStorage` |
| Wishlist | Saved in the visitor's `localStorage` |
### Deliberately doesn't ❌
These forms have complete UIs and real validation, but on submit they show a
plain notice that this build has no backend, instead of faking success:
- Login and register (`/login`, `/register`)
- Placing an order (`/checkout`)
- Newsletter signup
The admin dashboard was dropped entirely — without a server there is nothing
for it to administer. **No visitor data is ever sent anywhere.**
---
## 🛠️ Tech stack
- **Vite 8** — bundler and dev server.
- **React 18** + **React Router 7** for client-side routing.
- **TypeScript**, strict mode.
- **Tailwind CSS 3** with custom design tokens (`tailwind.config.ts`).
- **Zustand** for cart and wishlist state, persisted to `localStorage`.
- **Zod** for form validation.
- **Vazirmatn** via `@fontsource-variable/vazirmatn` — self-hosted, so no
request ever leaves for Google's servers.
- **sharp**, **opentype.js** and **resvg** in build scripts only, for
thumbnails, the favicon and the social card.
### Why Vite and not Next.js?
Earlier versions of this project were built with Next.js (App Router). Since
the site has no backend and is published statically to GitHub Pages, the
server-side half of Next.js — SSR, API routes, runtime image optimisation —
was never being used. Vite produces the same final artifact with a simpler
config and a much faster build.
**What that gave up, and how it's paid back:** Next.js pre-rendered every page
at build time, so each product had its own HTML file. A plain Vite SPA has
one `index.html` and lets React Router sort out the rest — which means every
URL but the home page was served through the 404 fallback, answering with an
HTTP 404 and the site-wide title. [`scripts/prerender.mjs`](scripts/prerender.mjs)
puts that back: after the bundle is built it writes a real
`dist/<route>/index.html` for all 44 indexable URLs, each carrying its own
head. The body is still filled in by React — this is metadata prerendering,
not server rendering — but the pages now return 200 with their own titles,
which is what indexing and link previews depend on.
---
## 🚀 Installation and usage
```bash
npm install
npm run dev
```
Then open <http://localhost:3000>.
### Building
```bash
npm run build
```
The static site lands in `dist/`. To preview exactly what will be published:
```bash
npm start
```
### Scripts
| Command | What it does |
| --- | --- |
| `npm run dev` | Regenerates assets, then starts Vite on port 3000 |
| `npm run build` | Regenerates assets, typechecks, builds into `dist/`, prerenders every route |
| `npm start` | Serves the built `dist/` locally |
| `npm run lint` | ESLint, including the a11y rules |
| `npm run typecheck` | `tsc --noEmit` |
| `npm run build:images` | Rebuilds the 400px `*-thumb.webp` product thumbnails |
| `npm run build:data` | Rebuilds `src/data/summaries.json` from `products.json` |
| `npm run build:sitemap` | Rebuilds `public/sitemap.xml` |
| `npm run build:favicon` | Redraws `favicon.svg`, `favicon.ico`, `apple-touch-icon.png` |
| `npm run build:og` | Redraws `public/og-image.png`, the 1200×630 social card |
| `npm run build:hero` | Recomposes `public/hero.webp` from the featured product photos |
> The image, data and sitemap steps run automatically before `dev` and
> `build`. `summaries.json` and `sitemap.xml` are generated — don't hand-edit
> them. The favicon, social card and hero are design assets: they are
> committed, and only rebuilt when you change the brand or the products they
> feature.
---
## 📂 Code structure
```
index.html Vite entry point; site-wide <head> tags live here
vite.config.ts Base path, aliases, and the Pages output files
scripts/
build-thumbnails.mjs 400px WebP thumbnails for catalogue images
build-summaries.mjs Generates the light product records
build-sitemap.mjs Generates public/sitemap.xml
prerender.mjs Writes one HTML file per indexable route
build-favicon.mjs Draws the icons from the font's own "ت" glyph
build-og-image.mjs Draws the 1200×630 social card
build-hero.mjs Composes the home page's hero image
lib/routes.mjs The indexable routes + their metadata and JSON-LD
lib/woff.mjs Unpacks a WOFF to a TTF the drawing tools can read
src/
main.tsx Root render + BrowserRouter
App.tsx Layout shell and route table
routes/ One component per page
components/
Link.tsx Router link with a next/link-shaped API
PageMeta.tsx Per-route title, description, canonical, og:url
ErrorBoundary.tsx App-wide error boundary
layout/ home/ product/ shop/ cart/ checkout/ auth/ ui/
hooks/
useRouter.ts Small navigation helper
useHydrated.ts True once localStorage state has loaded
store/ Zustand cart and wishlist stores
data/
products.json Full catalogue
summaries.json Generated light records for cards
categories.json Categories
lib/
products.ts Reads over the full record (product page only)
summaries.ts Filter, sort and search over light records
format.ts Persian number, price and date formatting
validation.ts Zod schemas
email.ts The email rule, dependency-free (see below)
chatReplies.ts Canned support-chat replies
site.ts Site name, URL, repo, and the demo notice
```
### Why two data files?
| File | Contents | Used by |
| --- | --- | --- |
| `products.json` | Full records, including descriptions and spec tables | `lib/products.ts` only (product detail page) |
| `summaries.json` | Just the fields a product card needs | Everything else — listings, filters, search, cart |
Descriptions and spec tables are roughly **70%** of the catalogue's bytes and
never appear in a listing. If a component used on a listing imported
`lib/products.ts`, all of that would land in that route's bundle — so those
components always use `lib/summaries.ts`.
---
## 🖼️ Adding or editing products
1. Add the record to [`src/data/products.json`](src/data/products.json).
2. Drop the images into `public/` as **WebP**.
3. Run `npm run build:images` to generate the 400px thumbnails.
`summaries.json` and `sitemap.xml` regenerate on the next `dev` or `build`.
---
## ⚡ Performance notes
- **Route-level code splitting.** Every route except the home page is behind
`React.lazy`, so a visitor who never leaves the landing page never downloads
the checkout schemas or the product gallery. The home page is eager on
purpose — splitting it would only add a request that every first visit needs.
- **Zod is not in the first download.** It used to be, because the footer's
newsletter box imported the shared schemas and the footer is on every page —
14 KB gzipped to validate one text field. That form now uses
`src/lib/email.ts`, which `validation.ts` also builds its email schema on, so
the rule stays in one place and Zod loads only with the forms that need it.
- **Two sizes per image.** Cards render at roughly 180–280 CSS px, so
`build-thumbnails.mjs` emits a 400px WebP next to each full-size image; the
large file is only fetched on a product page.
- **A hero built at the size it renders.** `hero.webp` is composed at
1160×870, exactly twice its layout box, so it is sharp on a 2× screen and
never upscaled or cropped on a 1× one.
- **Lazy images below the fold.** Everything except the hero is
`loading="lazy"`, and every image sits in a fixed-aspect-ratio box, so
loading one never shifts the layout.
- **Self-hosted fonts, subset by script.** The Arabic and Latin subsets load
separately, so a page with no Latin text doesn't pay for Latin glyphs.
A cold load of the home page is about **165 KB** over 22 requests: one ~89 KB
gzipped JS bundle, 8 KB of CSS, the two font subsets, and the hero image.
---
## 🛡️ Security notes
The published output is entirely static, so the whole server-side class of
vulnerabilities — SQL injection, auth bypass, file upload — cannot exist here;
there is no server-side code to attack. What is in place:
- **Content-Security-Policy** as a `<meta>` tag, with `object-src 'none'`,
`base-uri 'self'`, `form-action 'none'`, `worker-src 'none'` and
`frame-src 'none'`. The published build goes further than the source: the
file in the repo allows inline script because Vite's dev server injects its
HMR client that way, and `cspForProduction()` in `vite.config.ts` strips
`'unsafe-inline'` out of `script-src` when it writes `dist/index.html` —
the production bundle has no inline script to allow.
- **No `dangerouslySetInnerHTML` anywhere** — every string goes through
React's escaping.
- **`localStorage` is treated as untrusted.** It is fully user-writable, so
every persisted cart and wishlist line is re-validated on load: negative
prices and quantities, non-numeric values, duplicate ids and image paths
that are not really paths (`javascript:`, `//another-host/x.png`, `..`) are
dropped or clamped.
- **The query string is treated the same way.** The shop reads its filters,
sort and page number out of the URL, so every one of them is validated
against the real brands, sort keys and ratings before it is used.
- **Zod validation on every form**, with `rel="noopener noreferrer"` on every
external link.
- **No secrets in the repository** — the project has no secret to keep.
- **`npm audit` reports 0 vulnerabilities.**
### Known limitation
Real HTTP security headers (`X-Frame-Options`, or `frame-ancestors` against
clickjacking) can't be set on GitHub Pages: the service doesn't allow custom
response headers, and browsers ignore `frame-ancestors` when it arrives via
`<meta>`. Hosting that supports headers — Netlify, Vercel, Cloudflare Pages —
is the fix if those matter.
> Client-side validation is not a security boundary. Here it exists purely to
> give the visitor honest feedback, because there is no server that could be
> tricked into trusting the input.
---
## 🎨 Customization
**Colours, spacing and shadows** are design tokens in
[`tailwind.config.ts`](tailwind.config.ts). The brand ramp drives the header,
buttons, links and the generated icons:
```ts
brand: {
50: "#eef4ff",
600: "#1d45f5", // primary actions, logo badge, favicon
700: "#1633e1", // hover state
// ...
}
```
After changing `brand-600`, rerun `npm run build:favicon`,
`npm run build:og` and `npm run build:hero` so the icons, the social card and
the hero all match.
**Store name, tagline, URL and contact details** live in
[`src/lib/site.ts`](src/lib/site.ts). The phone, email and address are
deliberate placeholders — replace them before using this for a real shop.
`site.url` is read by the app, the sitemap and the prerenderer alike.
Publishing under a different path or domain takes two edits: `PROJECT_BASE`
in [`vite.config.ts`](vite.config.ts) (or `VITE_BASE_PATH` at build time) for
the URL prefix, and `site.url` above for the canonical/OG/sitemap URLs. A
custom domain served from the root wants the base set to `/`.
---
## 📄 License
Released under the [MIT License](LICENSE). This started life as a fork of an
open-source storefront template by Aleksandar Kuzmanović; that copyright line
stays in `LICENSE` alongside the one for this rewrite.
看看同类模板
对比同技术栈与用途的模板,找到更适合的视觉与内容结构。

free.website.templates
Free OpenSource Website Page Templates Collection by Vontext: Vite + React + TypeScript + TailwindCSS
Vite · 后台

alexkpotstore
Digital storefront for 3D prints, Notion templates, VS Code themes, and wallpapers built with React and Vite
Vite · 电商

templatevibecode
Free, MIT-licensed website templates (landing pages, company profile, storefront) built with React, Vite and T…
Vite · 电商

webspatial-shop
WebSpatial storefront starter with React and 3D product previews.
Vite · 电商

Next.js Commerce
Next.js Commerce 是 Vercel 团队维护的电商启动模板,基于 Next.js App Router 构建,采用服务端渲染、React Server Components、Server Actions …
Next.js · 电商

astro-ecommerce
Astro Ecommerce - Ready to use components
Astro · 电商
