summaryrefslogtreecommitdiffhomepage
path: root/packages/web/src/middleware.ts
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-02-09 11:34:35 -0600
committerGitHub <[email protected]>2026-02-09 11:34:35 -0600
commitdc53086c1e73d43d3a28fc4cdf161e83d09b1877 (patch)
tree45a1d0e38de958d0886a5120b2806b21db74145b /packages/web/src/middleware.ts
parentf74c0339cc6315f7e7743e26b7eab47ce026c239 (diff)
downloadopencode-dc53086c1e73d43d3a28fc4cdf161e83d09b1877.tar.gz
opencode-dc53086c1e73d43d3a28fc4cdf161e83d09b1877.zip
wip(docs): i18n (#12681)
Diffstat (limited to 'packages/web/src/middleware.ts')
-rw-r--r--packages/web/src/middleware.ts77
1 files changed, 77 insertions, 0 deletions
diff --git a/packages/web/src/middleware.ts b/packages/web/src/middleware.ts
new file mode 100644
index 000000000..5b2d33666
--- /dev/null
+++ b/packages/web/src/middleware.ts
@@ -0,0 +1,77 @@
+import { defineMiddleware } from "astro:middleware"
+import { matchLocale } from "./i18n/locales"
+
+function docsAlias(pathname: string) {
+ const hit = /^\/docs\/([^/]+)(\/.*)?$/.exec(pathname)
+ if (!hit) return null
+
+ const value = hit[1] ?? ""
+ const tail = hit[2] ?? ""
+ const locale = matchLocale(value)
+ if (!locale) return null
+ if (locale === "root") return `/docs${tail}`
+ if (value === locale) return null
+
+ return `/docs/${locale}${tail}`
+}
+
+function localeFromCookie(header: string | null) {
+ if (!header) return null
+ const raw = header
+ .split(";")
+ .map((x) => x.trim())
+ .find((x) => x.startsWith("oc_locale="))
+ ?.slice("oc_locale=".length)
+ if (!raw) return null
+ return matchLocale(raw)
+}
+
+function localeFromAcceptLanguage(header: string | null) {
+ if (!header) return "root"
+
+ const items = header
+ .split(",")
+ .map((raw) => raw.trim())
+ .filter(Boolean)
+ .map((raw) => {
+ const parts = raw.split(";").map((x) => x.trim())
+ const lang = parts[0] ?? ""
+ const q = parts
+ .slice(1)
+ .find((x) => x.startsWith("q="))
+ ?.slice(2)
+ return {
+ lang,
+ q: q ? Number.parseFloat(q) : 1,
+ }
+ })
+ .sort((a, b) => b.q - a.q)
+
+ const locale = items
+ .map((item) => item.lang)
+ .filter((lang) => lang && lang !== "*")
+ .map((lang) => matchLocale(lang))
+ .find((lang) => lang)
+
+ return locale ?? "root"
+}
+
+export const onRequest = defineMiddleware((ctx, next) => {
+ const alias = docsAlias(ctx.url.pathname)
+ if (alias) {
+ const url = new URL(ctx.request.url)
+ url.pathname = alias
+ return ctx.redirect(url.toString(), 302)
+ }
+
+ if (ctx.url.pathname !== "/docs" && ctx.url.pathname !== "/docs/") return next()
+
+ const locale =
+ localeFromCookie(ctx.request.headers.get("cookie")) ??
+ localeFromAcceptLanguage(ctx.request.headers.get("accept-language"))
+ if (!locale || locale === "root") return next()
+
+ const url = new URL(ctx.request.url)
+ url.pathname = `/docs/${locale}/`
+ return ctx.redirect(url.toString(), 302)
+})