Kaynağa Gözat

fix(web): sync docs locale cookie on alias redirects (#13109)

Jun 7 ay önce
ebeveyn
işleme
9f20e0d14b

+ 5 - 0
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 {

+ 24 - 7
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}/`)
 })