diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index c12675f..d161749 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -9,6 +9,8 @@ on:
- 'README.md'
- 'CHANGELOG.md'
- 'zensical.toml'
+ - 'zensical.zh-TW.toml'
+ - 'i18n/**'
- 'pyproject.toml'
- 'uv.lock'
- '.github/workflows/docs.yml'
@@ -20,6 +22,8 @@ on:
- 'README.md'
- 'CHANGELOG.md'
- 'zensical.toml'
+ - 'zensical.zh-TW.toml'
+ - 'i18n/**'
- 'pyproject.toml'
- 'uv.lock'
- '.github/workflows/docs.yml'
@@ -46,3 +50,6 @@ jobs:
- name: Build (strict)
run: uv run --no-sync zensical build --strict
+
+ - name: Build Traditional Chinese translation (strict)
+ run: uv run --no-sync zensical build --strict -f zensical.zh-TW.toml
diff --git a/.gitignore b/.gitignore
index 24fec37..0c53729 100644
--- a/.gitignore
+++ b/.gitignore
@@ -307,6 +307,7 @@ venv.bak/
# mkdocs documentation
/site
+/site-zh-TW
# mypy
.mypy_cache/
diff --git a/README.md b/README.md
index ba8429d..451b68c 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@
[](https://pypi.org/project/fastapi-cachex)
[](https://pypi.org/project/fastapi-cachex/)
-[English](https://github.com/allen0099/FastAPI-CacheX/blob/master/README.md) | [繁體中文](https://github.com/allen0099/FastAPI-CacheX/blob/master/docs/README.zh-TW.md)
+[English](https://github.com/allen0099/FastAPI-CacheX/blob/master/README.md) | [繁體中文](https://github.com/allen0099/FastAPI-CacheX/blob/master/i18n/zh-TW/docs/index.md)
A high-performance caching extension for FastAPI: a server-side response cache with `Cache-Control` and `ETag` support, application-level caching, and optional session management.
diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md
index 30947e5..1e7da2d 100644
--- a/docs/CONTRIBUTING.md
+++ b/docs/CONTRIBUTING.md
@@ -29,7 +29,9 @@ Please refer to our [Development Guide](DEVELOPMENT.md) for detailed instruction
## Pull Request Process
-1. Update the matching guide under `docs/` (and the README if the change belongs on the front page) when you change the interface
+1. Update the matching guide under `docs/` (and the README if the change belongs on the front page) when you change the interface. Only the English
+ pages need updating: the [Traditional Chinese translation](DEVELOPMENT.md#traditional-chinese-translation)
+ is allowed to lag behind them
2. Add an entry to the `## [Unreleased]` section of
[CHANGELOG.md](https://github.com/allen0099/FastAPI-CacheX/blob/master/CHANGELOG.md) if your change alters behaviour, adds public
API, or fixes something a user could have hit. That section is what the
diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md
index 8af5e4b..f3c45df 100644
--- a/docs/DEVELOPMENT.md
+++ b/docs/DEVELOPMENT.md
@@ -204,6 +204,25 @@ The **Docs** workflow (`.github/workflows/docs.yml`) and Read the Docs
(`.readthedocs.yaml`) both run `zensical build --strict`, so a broken link,
snippet path or docstring reference fails the PR.
+### Traditional Chinese translation
+
+A Traditional Chinese (`zh-TW`) translation is published at
+. It is a separate Read the
+Docs translation project built from `zensical.zh-TW.toml` (build settings in
+`i18n/zh-TW/.readthedocs.yaml`), and its pages live in `i18n/zh-TW/docs/` — not
+under `docs/`, which would pull them into the English site.
+
+```bash
+uv run zensical serve -f zensical.zh-TW.toml
+uv run zensical build --strict -f zensical.zh-TW.toml # also run by the Docs workflow
+```
+
+The English pages are the source of truth. The translation may lag behind
+them, and every translated page carries a banner saying so, with a link to the
+English original. Pages that are not translated yet are linked from the
+translation's navigation to the English site. When translating, follow the
+terms in [`i18n/zh-TW/GLOSSARY.md`](https://github.com/allen0099/FastAPI-CacheX/blob/master/i18n/zh-TW/GLOSSARY.md).
+
### Adding API reference pages
API pages live under `docs/api/` and are generated from docstrings (Google
diff --git a/docs/README.zh-TW.md b/docs/README.zh-TW.md
deleted file mode 100644
index fbb9674..0000000
--- a/docs/README.zh-TW.md
+++ /dev/null
@@ -1,279 +0,0 @@
-# FastAPI-Cache X
-
-[](https://github.com/astral-sh/uv)
-[](https://github.com/astral-sh/ruff)
-[](https://github.com/allen0099/FastAPI-CacheX/actions/workflows/test.yml)
-[](https://github.com/allen0099/FastAPI-CacheX/actions/workflows/coverage.yml)
-
-[](https://pepy.tech/project/fastapi-cachex)
-[](https://pepy.tech/project/fastapi-cachex)
-[](https://pepy.tech/project/fastapi-cachex)
-
-[](https://pypi.org/project/fastapi-cachex)
-[](https://pypi.org/project/fastapi-cachex/)
-
-[English](https://github.com/allen0099/FastAPI-CacheX/blob/master/README.md) | [繁體中文](README.zh-TW.md)
-
-FastAPI-CacheX 是一個為 FastAPI 框架設計的高效能快取擴充套件,提供伺服器端回應快取(支援 `Cache-Control` 與 `ETag`)、應用層快取和可選的 Session 管理。
-
-## 功能特點
-
-### HTTP 快取
-- 支援多種 HTTP 快取標頭
- - `Cache-Control`
- - `ETag`
- - `If-None-Match`
-- 支援多種後端快取系統
- - Redis
- - Memcached
- - 記憶體內快取
-- 可在回應中設定常用的 Cache-Control 指令(詳見下表)
-- 簡單易用的 `@cache` 裝飾器
-
-### Session 管理(可選擴充套件)
-- 使用 HMAC-SHA256 權杖簽名的安全 Session 管理
-- IP 地址和 User-Agent 綁定(可選安全功能)
-- Header、Bearer 權杖與 Cookie 傳輸(Cookie 需使用 `FastAPICacheXSessionMiddleware`;
- 舊的 `SessionMiddleware` 已 deprecated,將於 0.4.0 移除,詳見
- [Session 管理指南](SESSION.md))
-- 自動 Session 更新(滑動過期)
-- 跨請求通訊的 Flash Messages
-- 支援多種後端(Redis、Memcached、記憶體內)
-- 完整的 Session 生命週期管理(建立、驗證、更新、失效)
-
-### Cache-Control 指令
-
-`@cache` 有兩個角色:替瀏覽器與中間層(CDN、反向代理)寫出 `Cache-Control` 標頭,以及在後端維護自己的伺服器端快取。大部分指令只影響前者:它們會寫進標頭,但伺服器端快取的行為不會因此改變。
-
-| 指令 | 設定方式 | 寫入標頭 | 對伺服器端快取的影響 |
-|--------------------------|-------------------------------------|--------------------|-------------------------------------------------------------|
-| `max-age` | `ttl=N` | :white_check_mark: | `N` 秒內直接回傳已儲存的回應,不執行 handler(`ttl=0` 或未設定:不直接回傳)。 |
-| `no-cache` | `no_cache=True` | :white_check_mark: | 每次都執行 handler;回應仍會儲存,`If-None-Match` 相符時回 304。 |
-| `no-store` | `no_store=True` | :white_check_mark: | 不讀取也不儲存,也不設定 ETag。 |
-| `private` | `private=True` | :white_check_mark: | 完全不經過後端;每次都執行 handler,ETag 重新驗證仍有效。 |
-| `public` | `public=True` | :white_check_mark: | 無(僅寫入標頭)。 |
-| `immutable` | `immutable=True` | :white_check_mark: | 無(僅寫入標頭)。 |
-| `must-revalidate` | `must_revalidate=True` | :white_check_mark: | 無(僅寫入標頭)。 |
-| `stale-while-revalidate` | `stale="revalidate", stale_ttl=N` | :white_check_mark: | 無(僅寫入標頭):伺服器端快取不會回傳過期內容。 |
-| `stale-if-error` | `stale="error", stale_ttl=N` | :white_check_mark: | 無(僅寫入標頭):handler 失敗時不會改用快取回應。 |
-| `s-maxage` | — | :x: | — |
-| `proxy-revalidate` | — | :x: | — |
-| `no-transform` | — | :x: | — |
-| `must-understand` | — | :x: | — |
-
-請求端的 `Cache-Control`(例如瀏覽器強制重新整理時送出的 `no-cache`、`max-age=0`)不會改變 `@cache` 的行為。這是刻意的設計:若請求標頭能繞過快取,任何用戶端都能讓每個請求直接打到 handler。條件式請求仍會處理:`If-None-Match` 相符時回 304。
-
-## 安裝指南
-
-```bash
-uv add fastapi-cachex
-```
-
-核心套件搭配記憶體後端即可運作;其餘後端與 Session 的選用傳輸方式以 extra 形式提供:
-
-| Extra | 安裝 | 帶入套件 | 用途 |
-|-------|------|---------|------|
-| `redis` | `uv add "fastapi-cachex[redis]"` | `redis[hiredis]`、`orjson` | `AsyncRedisCacheBackend` |
-| `memcache` | `uv add "fastapi-cachex[memcache]"` | `pymemcache` | `MemcachedBackend`(注意是 `memcache` 不是 `memcached`) |
-| `jwt` | `uv add "fastapi-cachex[jwt]"` | `PyJWT` | `SessionConfig(token_format="jwt")` |
-
-`starlette` extra 已移除:`itsdangerous` 改為基本依賴,`FastAPICacheXSessionMiddleware`
-在一般安裝下即可使用。
-
-可以合併安裝:`uv add "fastapi-cachex[redis,jwt]"`。
-
-### 開發版本安裝
-
-```bash
-uv add git+https://github.com/allen0099/FastAPI-CacheX.git
-```
-
-## 快速開始
-
-```python
-from fastapi import FastAPI
-from fastapi_cachex import cache
-from fastapi_cachex import CacheBackend
-
-app = FastAPI()
-
-
-@app.get("/")
-@cache(ttl=60) # 快取 60 秒
-async def read_root():
- return {"Hello": "World"}
-
-
-@app.get("/no-cache")
-@cache(no_cache=True) # 標記此端點為不可快取
-async def non_cache_endpoint():
- return {"Hello": "World"}
-
-
-@app.get("/no-store")
-@cache(no_store=True) # 標記此端點為不可儲存
-async def non_store_endpoint():
- return {"Hello": "World"}
-
-
-@app.get("/clear_cache")
-async def remove_cache(cache: CacheBackend):
- await cache.clear_path("/path/to/clear") # 清除特定路徑的快取
- # 模式比對的對象是完整金鑰,不是只有路徑
- await cache.clear_pattern("GET|||*|||/path/to/clear/*")
-```
-
-`clear_pattern` 以 glob 比對**完整邏輯金鑰**。HTTP 快取金鑰的形狀是
-`method|||host|||path|||query`,所以只寫路徑的模式一個都比不到——要按路徑清除請用
-`clear_path(path, include_params=True)`,`clear_pattern` 留給你自己組出來的金鑰。
-
-## 後端設定
-
-FastAPI-CacheX 支援多種快取後端。你可以使用 `BackendProxy` 輕鬆切換不同的後端。
-
-### 快取金鑰格式
-
-快取金鑰遵循以下格式以避免衝突:
-
-```
-{method}|||{host}|||{path}|||{query_params}
-```
-
-這確保:
-- 不同的 HTTP 方法 (GET、POST 等) 不會共享快取
-- 不同的主機不會共享快取(適合多租戶情境)
-- 不同的查詢參數將獲得各自獨立的快取項目
-- 同一端點配合不同參數可以獨立快取
-
-查詢參數依照客戶端送出的順序取用,不會排序,因此 `?a=1&b=2` 與 `?b=2&a=1`
-對同一個邏輯請求會是兩筆不同的快取項目。
-
-所有後端會自動為金鑰加上前綴(例如 `fastapi_cachex:`)以避免與其他應用程式衝突。
-
-### 快取命中行為
-
-當快取項目有效(在 TTL 內)時:
-- **預設行為**:直接返回快取內容,連同處理器當初產生的狀態碼與標頭,無需重新執行端點處理器
-- **帶有 `If-None-Match` 標頭**:如果 ETag 匹配則返回 HTTP 304 Not Modified
-- **帶有 `no-cache` 指令**:強制重新驗證以確定是否需要返回 304
-
-- **使用 `private=True`**:不讀也不寫共享後端,處理器每次都執行,只保留 `If-None-Match` 重新驗證
-
-這意味著**快取命中非常快速** - 端點處理器函式永遠不會被執行。
-
-只有成功的回應會被儲存。處理器**回傳**的非 2xx 回應(例如 `Response(..., status_code=404)`)
-會原樣送出且不寫入快取,因此暫時性錯誤不會覆蓋上一份好的條目;`206 Partial Content` 同樣不快取。
-`Set-Cookie` 永遠不會被存下或重播。
-
-### 快取監控端點
-
-`add_routes(app)` 會掛上兩個唯讀端點:`{prefix}/cached-hits`(各路由命中次數)與
-`{prefix}/cached-records`(目前所有快取條目,含內容預覽)。
-
-> [!WARNING]
-> **這兩個端點本身沒有任何認證。** `include_in_schema=False` 只是讓它們不出現在 OpenAPI 文件,
-> 猜到路徑的人照樣讀得到,而 `/cached-records` 會外洩快取內容預覽與整個路由結構。
-> 生產環境務必傳入 `dependencies=[Depends(你的認證)]`,或只掛在對內的應用上。
-
-> [!NOTE]
-> Redis 後端的 `ttl_remaining` 不可用:`get_cache_data()` 不會逐一查詢每個金鑰的 TTL,
-> 因此監控畫面會把 Redis 條目一律顯示為永不過期(實際過期仍由 Redis 執行)。
-
-### 記憶體快取 (預設後端)
-
-若未指定後端,FastAPI-CacheX 預設使用記憶體快取。
-適合開發和測試。後端會自動執行清理任務,每 60 秒移除過期項目。
-
-```python
-from fastapi_cachex.backends import MemoryBackend
-from fastapi_cachex import BackendProxy
-
-backend = MemoryBackend()
-BackendProxy.set(backend)
-```
-
-**注意**:記憶體快取不適合多處理程式的生產環境。
-每個處理程式維護其自己獨立的快取。
-
-### Memcached
-
-```python
-from fastapi_cachex.backends import MemcachedBackend
-from fastapi_cachex import BackendProxy
-
-backend = MemcachedBackend(servers=["localhost:11211"])
-BackendProxy.set(backend)
-```
-
-**限制**:
-- Memcached 協議沒有金鑰列舉能力,`clear_pattern()` 與 `get_all_keys()` 都是 no-op
- (回傳 `0`/`[]` 並發出 `RuntimeWarning`);建立在其上的 `CacheManager.clear()`
- 與 `clear_prefix()` 因此同樣無效
-- 金鑰使用 `fastapi_cachex:` 前綴以避免衝突;超過 Memcached 250 bytes 上限的金鑰
- 會自動改用 SHA-256 摘要
-- 如果需要基於模式的快取清除,請考慮使用 Redis 後端
-
-### Redis
-
-```python
-from fastapi_cachex.backends import AsyncRedisCacheBackend
-from fastapi_cachex import BackendProxy
-
-backend = AsyncRedisCacheBackend(host="127.0.0.1", port=6379, db=0)
-BackendProxy.set(backend)
-```
-
-**功能**:
-- 完全非同步實現
-- 支援基於模式的金鑰清除
-- 使用 SCAN 而非 KEYS 以保證生產環境安全(非阻塞)
-- 預設使用 `fastapi_cachex:` 前綴
-- 支援自訂金鑰前綴用於多租戶情境
-
-**自訂前綴範例**:
-
-```python
-backend = AsyncRedisCacheBackend(
- host="127.0.0.1",
- port=6379,
- key_prefix="myapp:cache:",
-)
-BackendProxy.set(backend)
-```
-
-## 效能考量
-
-### 快取命中效能
-
-當快取命中(在 TTL 內)時,回應會直接返回而無需執行端點處理器。這非常快速:
-
-```python
-@app.get("/expensive")
-@cache(ttl=3600) # 快取 1 小時
-async def expensive_operation():
- # 只在快取未命中時執行
- # 快取命中時,此函式不會被呼叫
- result = perform_expensive_calculation()
- return result
-```
-
-### 後端選擇
-
-- **MemoryBackend**:單處理程式開發時最快;不適合生產環境
-- **Memcached**:適合分散式系統;模式清除有限制
-- **Redis**:最適合生產環境;完全非同步、支援所有功能、非阻塞操作
-
-## 文件
-
-- [快取流程說明](CACHE_FLOW.md)
-- [開發指南](DEVELOPMENT.md)
-- [已知限制與待辦](https://github.com/allen0099/FastAPI-CacheX/issues)
-- [變更紀錄](https://github.com/allen0099/FastAPI-CacheX/blob/master/CHANGELOG.md)
-- [貢獻指南](CONTRIBUTING.md)
-- [Session 管理指南](SESSION.md) - 完整的 Session 功能使用指南
-- [State 管理指南](STATE.md) - OAuth/CSRF 一次性 state token
-- [JWT Claims 說明](JWT_CLAIMS.md) - JWT session token 的 claim 設計與擴展方式
-
-## 授權條款
-
-本專案採用 Apache License 2.0 授權條款 - 查看 [LICENSE](https://github.com/allen0099/FastAPI-CacheX/blob/master/LICENSE) 檔案了解更多細節。
diff --git a/i18n/zh-TW/.readthedocs.yaml b/i18n/zh-TW/.readthedocs.yaml
new file mode 100644
index 0000000..6ea6c2c
--- /dev/null
+++ b/i18n/zh-TW/.readthedocs.yaml
@@ -0,0 +1,20 @@
+# Read the Docs build of the Traditional Chinese translation:
+# https://fastapi-cachex.readthedocs.io/zh-tw/latest/
+# Same as the root .readthedocs.yaml, but built from zensical.zh-TW.toml. The
+# translation project points its "Build configuration file" setting here.
+version: 2
+
+build:
+ os: ubuntu-24.04
+ tools:
+ python: "3.14"
+ jobs:
+ install:
+ - pip install uv
+ - UV_PROJECT_ENVIRONMENT=$READTHEDOCS_VIRTUALENV_PATH uv sync --frozen --only-group docs --no-install-project
+ build:
+ html:
+ - UV_PROJECT_ENVIRONMENT=$READTHEDOCS_VIRTUALENV_PATH uv run --no-sync zensical build --strict -f zensical.zh-TW.toml
+ post_build:
+ - mkdir -p $READTHEDOCS_OUTPUT/html/
+ - cp -r site-zh-TW/* $READTHEDOCS_OUTPUT/html/
diff --git a/i18n/zh-TW/GLOSSARY.md b/i18n/zh-TW/GLOSSARY.md
new file mode 100644
index 0000000..d51e2ce
--- /dev/null
+++ b/i18n/zh-TW/GLOSSARY.md
@@ -0,0 +1,49 @@
+# 繁體中文翻譯詞彙表
+
+翻譯 `i18n/zh-TW/docs/` 時使用的統一譯名,採台灣慣用語。英文文件是唯一的
+正本,譯文可以落後,但不應與英文內容矛盾。
+
+## 原則
+
+- 程式碼、識別字、參數名稱、HTTP 標頭與指令保持原文,並以 inline code 標示:
+ `@cache`、`ttl`、`Cache-Control`、`no-store`、`If-None-Match`。
+- 程式碼區塊內的程式碼不翻譯,只翻譯註解。
+- 中文與英文、數字、inline code 之間加一個半形空格;中文句子使用全形標點。
+- 下表標示「保留」的詞在中文句子中直接使用英文。
+- 章節錨點(`#authenticated-endpoints` 等)由英文標題產生;連到英文文件時沿用英文錨點。
+
+## 詞彙
+
+| 英文 | 譯名 | 備註 |
+|------|------|------|
+| cache(名詞) | 快取 | |
+| cache(動詞) | 快取、存入快取 | |
+| cache hit / miss | 快取命中/未命中 | |
+| cache key | 快取鍵 | |
+| backend | 後端 | |
+| header | 標頭 | |
+| request / response | 請求/回應 | |
+| handler | 保留 | 指路由處理函式 |
+| route / endpoint | 路由/端點 | |
+| decorator | 裝飾器 | |
+| dependency | 依賴項 | FastAPI 的 dependency injection:依賴注入 |
+| middleware | 中介軟體 | |
+| directive | 指令 | `Cache-Control` 指令 |
+| revalidation | 重新驗證 | |
+| invalidate / invalidation | 使……失效/快取失效 | |
+| expire / expiration | 過期 | |
+| sliding expiration | 滑動過期 | |
+| TTL | 保留 | |
+| prefix / namespace | 前綴/命名空間 | |
+| atomic | 原子性、原子操作 | |
+| counter | 計數器 | |
+| lock | 鎖 | |
+| token | 權杖 | |
+| signature / sign | 簽章/簽署 | |
+| session | 保留(Session) | |
+| claim | 保留 | JWT claim |
+| state(OAuth) | 保留 | |
+| serialize / deserialize | 序列化/反序列化 | |
+| extra | 保留 | 套件的選用依賴,例:`redis` extra |
+| deprecated | 已棄用 | |
+| breaking change | 破壞性變更 | |
diff --git a/i18n/zh-TW/docs/index.md b/i18n/zh-TW/docs/index.md
new file mode 100644
index 0000000..c08da61
--- /dev/null
+++ b/i18n/zh-TW/docs/index.md
@@ -0,0 +1,97 @@
+# FastAPI-Cache X
+
+[](https://github.com/astral-sh/uv)
+[](https://github.com/astral-sh/ruff)
+[](https://github.com/allen0099/FastAPI-CacheX/actions/workflows/test.yml)
+[](https://github.com/allen0099/FastAPI-CacheX/actions/workflows/coverage.yml)
+
+[](https://pepy.tech/project/fastapi-cachex)
+[](https://pepy.tech/project/fastapi-cachex)
+[](https://pepy.tech/project/fastapi-cachex)
+
+[](https://pypi.org/project/fastapi-cachex)
+[](https://pypi.org/project/fastapi-cachex/)
+
+[English](https://github.com/allen0099/FastAPI-CacheX/blob/master/README.md) | [繁體中文](https://github.com/allen0099/FastAPI-CacheX/blob/master/i18n/zh-TW/docs/index.md)
+
+FastAPI-CacheX 是 FastAPI 的高效能快取擴充套件:提供支援 `Cache-Control` 與 `ETag` 的伺服器端回應快取、應用層快取,以及可選的 Session 管理。
+
+**文件:** (尚未翻譯的指南與完整 API 參考請見[英文文件](https://fastapi-cachex.readthedocs.io/en/latest/))
+
+## 功能特點
+
+- **HTTP 快取**:GET 路由專用的 `@cache` 裝飾器,支援 `Cache-Control`、
+ `ETag` / `If-None-Match`(304)與單一路由的快取失效。
+- **應用層快取**:`CacheManager` 可在自己的程式碼中快取任意 JSON 值,提供
+ 未命中時才計算的 `get_or_set()` 與原子性的「不存在才寫入」`add()`。
+- **後端**:記憶體、Redis 與 Memcached,支援原子操作的計數器、一次性取值與鎖。
+- **Session(可選)**:以 HMAC 簽章或 JWT 發行的 Session 權杖,可經由標頭、
+ Bearer 權杖或 Cookie 傳遞,支援滑動過期與 IP / User-Agent 綁定。
+- **OAuth state**:OAuth / OIDC 流程中用於防範 CSRF 的一次性 state 權杖。
+
+## 安裝
+
+```bash
+uv add fastapi-cachex
+```
+
+核心套件搭配記憶體後端即可使用;其他後端與 Session 的選用傳輸方式以 extra 提供:
+
+| Extra | 安裝 | 帶入套件 | 用途 |
+|-------|------|---------|------|
+| `redis` | `uv add "fastapi-cachex[redis]"` | `redis[hiredis]`、`orjson` | `AsyncRedisCacheBackend` |
+| `memcache` | `uv add "fastapi-cachex[memcache]"` | `pymemcache` | `MemcachedBackend`(注意是 `memcache`,不是 `memcached`) |
+| `jwt` | `uv add "fastapi-cachex[jwt]"` | `PyJWT` | `SessionConfig(token_format="jwt")` |
+
+Extra 可以組合:`uv add "fastapi-cachex[redis,jwt]"`。
+
+## 快速開始
+
+```python
+from fastapi import FastAPI
+
+from fastapi_cachex import AppCache, BackendProxy, cache
+from fastapi_cachex.backends import MemoryBackend
+
+app = FastAPI()
+BackendProxy.set(MemoryBackend()) # 或 AsyncRedisCacheBackend / MemcachedBackend
+
+
+@app.get("/items/{item_id}")
+@cache(ttl=60) # 60 秒內直接由快取回應,並支援 ETag 重新驗證
+async def read_item(item_id: int):
+ return {"item_id": item_id}
+
+
+def build_report() -> dict:
+ return {"total": 42} # 代表某個耗時的計算
+
+
+@app.get("/report")
+async def report(cache: AppCache):
+ # 在自己的程式碼中快取任意 JSON 值。
+ return await cache.get_or_set("report", build_report, ttl=300)
+```
+
+> [!WARNING]
+> 預設的快取鍵不包含使用者身分。需要驗證身分的端點請使用 `private=True`
+> 或依使用者區分的 key builder,詳見
+> [需驗證身分的端點](https://fastapi-cachex.readthedocs.io/en/latest/HTTP_CACHING/#authenticated-endpoints)(英文)。
+
+## 文件
+
+以下指南尚未翻譯,連結指向英文文件:
+
+- [HTTP 快取](https://fastapi-cachex.readthedocs.io/en/latest/HTTP_CACHING/):`@cache` 裝飾器、Cache-Control 指令、快取鍵、快取失效與監控路由
+- [快取流程](https://fastapi-cachex.readthedocs.io/en/latest/CACHE_FLOW/):快取請求內部的處理流程
+- [應用層快取](https://fastapi-cachex.readthedocs.io/en/latest/APP_CACHE/):`CacheManager`
+- [後端](https://fastapi-cachex.readthedocs.io/en/latest/BACKENDS/):選擇與設定後端、原子操作的基本功能
+- [Session 管理](https://fastapi-cachex.readthedocs.io/en/latest/SESSION/)與 [JWT claims](https://fastapi-cachex.readthedocs.io/en/latest/JWT_CLAIMS/)
+- [OAuth state](https://fastapi-cachex.readthedocs.io/en/latest/STATE/):一次性的 OAuth / CSRF state 權杖
+- [API 參考](https://fastapi-cachex.readthedocs.io/en/latest/api/http-caching/)
+- [開發指南](https://fastapi-cachex.readthedocs.io/en/latest/DEVELOPMENT/)與[貢獻指南](https://fastapi-cachex.readthedocs.io/en/latest/CONTRIBUTING/)
+- [變更紀錄](https://github.com/allen0099/FastAPI-CacheX/blob/master/CHANGELOG.md) · [已知限制與規劃中的工作](https://github.com/allen0099/FastAPI-CacheX/issues)
+
+## 授權
+
+本專案採用 Apache License 2.0 授權,詳見 [LICENSE](https://github.com/allen0099/FastAPI-CacheX/blob/master/LICENSE)。
diff --git a/i18n/zh-TW/overrides/main.html b/i18n/zh-TW/overrides/main.html
new file mode 100644
index 0000000..1302c22
--- /dev/null
+++ b/i18n/zh-TW/overrides/main.html
@@ -0,0 +1,9 @@
+{% extends "base.html" %}
+
+{#- English is the source of truth and the translation may lag behind it
+ (see issue #89), so every page says so and links to its original. -#}
+{% block announce %}
+ 本頁譯自英文文件,內容可能未反映最新版本。以
+ 英文原文
+ 為準。
+{% endblock %}
diff --git a/zensical.toml b/zensical.toml
index 62397b2..0295cf4 100644
--- a/zensical.toml
+++ b/zensical.toml
@@ -42,6 +42,18 @@ nav = [
{ "Changelog" = "changelog.md" },
]
+# Language switcher. The Traditional Chinese site is a Read the Docs
+# translation project built from zensical.zh-TW.toml.
+[[project.extra.alternate]]
+name = "English"
+link = "https://fastapi-cachex.readthedocs.io/en/latest/"
+lang = "en"
+
+[[project.extra.alternate]]
+name = "繁體中文"
+link = "https://fastapi-cachex.readthedocs.io/zh-tw/latest/"
+lang = "zh-Hant"
+
[project.theme]
language = "en"
features = [
diff --git a/zensical.zh-TW.toml b/zensical.zh-TW.toml
new file mode 100644
index 0000000..c230a0c
--- /dev/null
+++ b/zensical.zh-TW.toml
@@ -0,0 +1,114 @@
+# Traditional Chinese documentation site, a Read the Docs translation of the
+# English site (zensical.toml). See "Traditional Chinese translation" in
+# docs/DEVELOPMENT.md.
+#
+# uv run zensical serve -f zensical.zh-TW.toml
+# uv run zensical build --strict -f zensical.zh-TW.toml
+#
+# The pages live outside docs/ because Zensical has no exclude_docs: anything
+# under docs/ would also be built into the English site.
+
+[project]
+site_name = "FastAPI-CacheX"
+site_description = "FastAPI 的 HTTP 快取、應用層快取與 Session 管理。"
+site_url = "https://fastapi-cachex.readthedocs.io/zh-tw/latest/"
+repo_url = "https://github.com/allen0099/FastAPI-CacheX"
+repo_name = "allen0099/FastAPI-CacheX"
+edit_uri = "edit/master/i18n/zh-TW/docs/"
+docs_dir = "i18n/zh-TW/docs"
+site_dir = "site-zh-TW"
+
+# Pages that are not translated (yet) point at the English site. Swap an entry
+# to the local file once its translation lands.
+nav = [
+ { "首頁" = "index.md" },
+ { "指南" = [
+ { "HTTP 快取(英文)" = "https://fastapi-cachex.readthedocs.io/en/latest/HTTP_CACHING/" },
+ { "快取流程(英文)" = "https://fastapi-cachex.readthedocs.io/en/latest/CACHE_FLOW/" },
+ { "應用層快取(英文)" = "https://fastapi-cachex.readthedocs.io/en/latest/APP_CACHE/" },
+ { "後端(英文)" = "https://fastapi-cachex.readthedocs.io/en/latest/BACKENDS/" },
+ { "Session 管理(英文)" = "https://fastapi-cachex.readthedocs.io/en/latest/SESSION/" },
+ { "JWT claims(英文)" = "https://fastapi-cachex.readthedocs.io/en/latest/JWT_CLAIMS/" },
+ { "OAuth state(英文)" = "https://fastapi-cachex.readthedocs.io/en/latest/STATE/" },
+ ] },
+ { "API 參考(英文)" = "https://fastapi-cachex.readthedocs.io/en/latest/api/http-caching/" },
+ { "開發(英文)" = [
+ { "開發指南" = "https://fastapi-cachex.readthedocs.io/en/latest/DEVELOPMENT/" },
+ { "貢獻指南" = "https://fastapi-cachex.readthedocs.io/en/latest/CONTRIBUTING/" },
+ ] },
+ { "變更紀錄(英文)" = "https://github.com/allen0099/FastAPI-CacheX/blob/master/CHANGELOG.md" },
+]
+
+[project.extra]
+# Base of the English original; the "may be outdated" banner links each page
+# to its counterpart there.
+english_site = "https://fastapi-cachex.readthedocs.io/en/latest/"
+
+[[project.extra.alternate]]
+name = "English"
+link = "https://fastapi-cachex.readthedocs.io/en/latest/"
+lang = "en"
+
+[[project.extra.alternate]]
+name = "繁體中文"
+link = "https://fastapi-cachex.readthedocs.io/zh-tw/latest/"
+lang = "zh-Hant"
+
+[project.theme]
+language = "zh-Hant"
+custom_dir = "i18n/zh-TW/overrides"
+features = [
+ "content.action.edit",
+ "content.code.annotate",
+ "content.code.copy",
+ "content.tabs.link",
+ "navigation.footer",
+ "navigation.indexes",
+ "navigation.instant",
+ "navigation.path",
+ "navigation.sections",
+ "navigation.top",
+ "navigation.tracking",
+ "search.highlight",
+]
+
+[[project.theme.palette]]
+media = "(prefers-color-scheme)"
+toggle.icon = "lucide/sun-moon"
+toggle.name = "切換為淺色模式"
+
+[[project.theme.palette]]
+media = "(prefers-color-scheme: light)"
+scheme = "default"
+toggle.icon = "lucide/sun"
+toggle.name = "切換為深色模式"
+
+[[project.theme.palette]]
+media = "(prefers-color-scheme: dark)"
+scheme = "slate"
+toggle.icon = "lucide/moon"
+toggle.name = "切換為跟隨系統"
+
+# Same extensions as the English site, so a translated page renders like its
+# original.
+[project.markdown_extensions]
+admonition = {}
+github-callouts = {}
+attr_list = {}
+def_list = {}
+footnotes = {}
+md_in_html = {}
+tables = {}
+toc.permalink = true
+pymdownx.details = {}
+pymdownx.emoji.emoji_index = "zensical.extensions.emoji.twemoji"
+pymdownx.emoji.emoji_generator = "pymdownx.emoji.to_alt"
+pymdownx.highlight.anchor_linenums = true
+pymdownx.highlight.line_spans = "__span"
+pymdownx.highlight.pygments_lang_class = true
+pymdownx.inlinehilite = {}
+pymdownx.superfences = {}
+pymdownx.tabbed.alternate_style = true
+pymdownx.tasklist.custom_checkbox = true
+pymdownx.snippets.base_path = ["."]
+pymdownx.snippets.check_paths = true