wip(docs): i18n (#12681)
This commit is contained in:
77
packages/web/src/middleware.ts
Normal file
77
packages/web/src/middleware.ts
Normal file
@@ -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)
|
||||
})
|
||||
Reference in New Issue
Block a user