summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJun <[email protected]>2026-02-13 20:12:28 +0900
committerGitHub <[email protected]>2026-02-13 05:12:28 -0600
commit9f20e0d14b1d7db2167b2a81523a2521fe1c3b73 (patch)
tree2590f67537fe47a3decab7813eb0b21e41ad8150
parentebb907d646022d2e7bb8effc164e1f09943d64a9 (diff)
downloadopencode-9f20e0d14b1d7db2167b2a81523a2521fe1c3b73.tar.gz
opencode-9f20e0d14b1d7db2167b2a81523a2521fe1c3b73.zip
fix(web): sync docs locale cookie on alias redirects (#13109)
-rw-r--r--packages/app/src/context/language.tsx5
-rw-r--r--packages/web/src/middleware.ts31
2 files changed, 29 insertions, 7 deletions
diff --git a/packages/app/src/context/language.tsx b/packages/app/src/context/language.tsx
index a5d894e62..b21ec6d3c 100644
--- a/packages/app/src/context/language.tsx
+++ b/packages/app/src/context/language.tsx
@@ -57,6 +57,10 @@ export type Locale =
type RawDictionary = typeof en & typeof uiEn
type Dictionary = i18n.Flatten<RawDictionary>
+function cookie(locale: Locale) {
+ return `oc_locale=${encodeURIComponent(locale)}; Path=/; Max-Age=31536000; SameSite=Lax`
+}
+
const LOCALES: readonly Locale[] = [
"en",
"zh",
@@ -199,6 +203,7 @@ export const { use: useLanguage, provider: LanguageProvider } = createSimpleCont
createEffect(() => {
if (typeof document !== "object") return
document.documentElement.lang = locale()
+ document.cookie = cookie(locale())
})
return {
diff --git a/packages/web/src/middleware.ts b/packages/web/src/middleware.ts
index 97d085dfb..cf9f97b0b 100644
--- a/packages/web/src/middleware.ts
+++ b/packages/web/src/middleware.ts
@@ -12,7 +12,28 @@ function docsAlias(pathname: string) {
const next = locale === "root" ? `/docs${tail}` : `/docs/${locale}${tail}`
if (next === pathname) return null
- return next
+ return {
+ path: next,
+ locale,
+ }
+}
+
+function cookie(locale: string) {
+ const value = locale === "root" ? "en" : locale
+ return `oc_locale=${encodeURIComponent(value)}; Path=/; Max-Age=31536000; SameSite=Lax`
+}
+
+function redirect(url: URL, path: string, locale?: string) {
+ const next = new URL(url.toString())
+ next.pathname = path
+ const headers = new Headers({
+ Location: next.toString(),
+ })
+ if (locale) headers.set("Set-Cookie", cookie(locale))
+ return new Response(null, {
+ status: 302,
+ headers,
+ })
}
function localeFromCookie(header: string | null) {
@@ -59,9 +80,7 @@ function localeFromAcceptLanguage(header: string | null) {
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)
+ return redirect(ctx.url, alias.path, alias.locale)
}
if (ctx.url.pathname !== "/docs" && ctx.url.pathname !== "/docs/") return next()
@@ -71,7 +90,5 @@ export const onRequest = defineMiddleware((ctx, next) => {
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)
+ return redirect(ctx.url, `/docs/${locale}/`)
})