diff --git a/packages/console/app/script/generate-sitemap.ts b/packages/console/app/script/generate-sitemap.ts index 6cbffcb8516..bdce205b904 100755 --- a/packages/console/app/script/generate-sitemap.ts +++ b/packages/console/app/script/generate-sitemap.ts @@ -3,6 +3,7 @@ import { readdir, writeFile } from "fs/promises" import { join, dirname } from "path" import { fileURLToPath } from "url" import { config } from "../src/config.js" +import { LOCALES, route } from "../src/lib/language.js" const __dirname = dirname(fileURLToPath(import.meta.url)) const BASE_URL = config.baseUrl @@ -27,12 +28,14 @@ async function getMainRoutes(): Promise { { path: "/zen", priority: 0.8, changefreq: "weekly" }, ] - for (const route of staticRoutes) { - routes.push({ - url: `${BASE_URL}${route.path}`, - priority: route.priority, - changefreq: route.changefreq, - }) + for (const item of staticRoutes) { + for (const locale of LOCALES) { + routes.push({ + url: `${BASE_URL}${route(locale, item.path)}`, + priority: item.priority, + changefreq: item.changefreq, + }) + } } return routes @@ -50,11 +53,13 @@ async function getDocsRoutes(): Promise { const slug = file.replace(".mdx", "") const path = slug === "index" ? "/docs/" : `/docs/${slug}` - routes.push({ - url: `${BASE_URL}${path}`, - priority: slug === "index" ? 0.9 : 0.7, - changefreq: "weekly", - }) + for (const locale of LOCALES) { + routes.push({ + url: `${BASE_URL}${route(locale, path)}`, + priority: slug === "index" ? 0.9 : 0.7, + changefreq: "weekly", + }) + } } } catch (error) { console.error("Error reading docs directory:", error) diff --git a/packages/console/app/src/app.tsx b/packages/console/app/src/app.tsx index 3d16a64ab7c..3eb70606a45 100644 --- a/packages/console/app/src/app.tsx +++ b/packages/console/app/src/app.tsx @@ -8,11 +8,13 @@ import "@ibm/plex/css/ibm-plex.css" import "./app.css" import { LanguageProvider } from "~/context/language" import { I18nProvider } from "~/context/i18n" +import { strip } from "~/lib/language" export default function App() { return ( ( diff --git a/packages/console/app/src/component/footer.tsx b/packages/console/app/src/component/footer.tsx index 45dae87ecfe..d81bf324762 100644 --- a/packages/console/app/src/component/footer.tsx +++ b/packages/console/app/src/component/footer.tsx @@ -26,13 +26,13 @@ export function Footer() {
{i18n.t("footer.x")} diff --git a/packages/console/app/src/component/header.tsx b/packages/console/app/src/component/header.tsx index 3eca8b88c11..50f1b73d39d 100644 --- a/packages/console/app/src/component/header.tsx +++ b/packages/console/app/src/component/header.tsx @@ -20,6 +20,7 @@ import { github } from "~/lib/github" import { createEffect, onCleanup } from "solid-js" import { config } from "~/config" import { useI18n } from "~/context/i18n" +import { useLanguage } from "~/context/language" import "./header-context-menu.css" const isDarkMode = () => window.matchMedia("(prefers-color-scheme: dark)").matches @@ -38,6 +39,7 @@ const fetchSvgContent = async (svgPath: string): Promise => { export function Header(props: { zen?: boolean; hideGetStarted?: boolean }) { const navigate = useNavigate() const i18n = useI18n() + const language = useLanguage() const githubData = createAsync(() => github()) const starCount = createMemo(() => githubData()?.stars @@ -121,7 +123,7 @@ export function Header(props: { zen?: boolean; hideGetStarted?: boolean }) { return (
- + OpenCode OpenCode @@ -142,7 +144,7 @@ export function Header(props: { zen?: boolean; hideGetStarted?: boolean }) { {i18n.t("nav.context.copyWordmark")} -
diff --git a/packages/console/app/src/routes/black/subscribe/[plan].tsx b/packages/console/app/src/routes/black/subscribe/[plan].tsx index 347be7419ca..644d87d9b32 100644 --- a/packages/console/app/src/routes/black/subscribe/[plan].tsx +++ b/packages/console/app/src/routes/black/subscribe/[plan].tsx @@ -15,6 +15,7 @@ import { Modal } from "~/component/modal" import { BillingTable } from "@opencode-ai/console-core/schema/billing.sql.js" import { Billing } from "@opencode-ai/console-core/billing.js" import { useI18n } from "~/context/i18n" +import { useLanguage } from "~/context/language" import { formError } from "~/lib/form-error" const plansMap = Object.fromEntries(plans.map((p) => [p.id, p])) as Record @@ -267,6 +268,7 @@ function IntentForm(props: { plan: PlanID; workspaceID: string; onSuccess: (data export default function BlackSubscribe() { const params = useParams() const i18n = useI18n() + const language = useLanguage() const planData = plansMap[(params.plan as PlanID) ?? "20"] ?? plansMap["20"] const plan = planData.id @@ -467,7 +469,7 @@ export default function BlackSubscribe() {

{i18n.t("black.finePrint.beforeTerms")} ·{" "} - {i18n.t("black.finePrint.terms")} + {i18n.t("black.finePrint.terms")}

diff --git a/packages/console/app/src/routes/black/workspace.tsx b/packages/console/app/src/routes/black/workspace.tsx index 03950a24333..106e8a23ea8 100644 --- a/packages/console/app/src/routes/black/workspace.tsx +++ b/packages/console/app/src/routes/black/workspace.tsx @@ -220,13 +220,13 @@ export default function BlackWorkspace() { {i18n.t("nav.github")} [{starCount()}] - {i18n.t("nav.docs")} + {i18n.t("nav.docs")} - {i18n.t("legal.privacy")} + {i18n.t("legal.privacy")} - {i18n.t("legal.terms")} + {i18n.t("legal.terms")}
diff --git a/packages/console/app/src/routes/brand/index.tsx b/packages/console/app/src/routes/brand/index.tsx index a1bc6c54cf1..eda3c84728d 100644 --- a/packages/console/app/src/routes/brand/index.tsx +++ b/packages/console/app/src/routes/brand/index.tsx @@ -1,10 +1,10 @@ import "./index.css" -import { Title, Meta, Link } from "@solidjs/meta" +import { Title, Meta } from "@solidjs/meta" import { Header } from "~/component/header" -import { config } from "~/config" import { Footer } from "~/component/footer" import { Legal } from "~/component/legal" import { useI18n } from "~/context/i18n" +import { LocaleLinks } from "~/component/locale-links" import previewLogoLight from "../../asset/brand/preview-opencode-logo-light.png" import previewLogoDark from "../../asset/brand/preview-opencode-logo-dark.png" import previewWordmarkLight from "../../asset/brand/preview-opencode-wordmark-light.png" @@ -56,7 +56,7 @@ export default function Brand() { return (
{i18n.t("brand.title")} - +
diff --git a/packages/console/app/src/routes/changelog/index.tsx b/packages/console/app/src/routes/changelog/index.tsx index 595ae9d1b6d..54f037479aa 100644 --- a/packages/console/app/src/routes/changelog/index.tsx +++ b/packages/console/app/src/routes/changelog/index.tsx @@ -1,15 +1,15 @@ import "./index.css" -import { Title, Meta, Link } from "@solidjs/meta" +import { Title, Meta } from "@solidjs/meta" import { createAsync } from "@solidjs/router" import { Header } from "~/component/header" import { Footer } from "~/component/footer" import { Legal } from "~/component/legal" -import { config } from "~/config" import { changelog } from "~/lib/changelog" import type { HighlightGroup } from "~/lib/changelog" import { For, Show, createSignal } from "solid-js" import { useI18n } from "~/context/i18n" import { useLanguage } from "~/context/language" +import { LocaleLinks } from "~/component/locale-links" function formatDate(dateString: string, locale: string) { const date = new Date(dateString) @@ -107,7 +107,7 @@ export default function Changelog() { return (
{i18n.t("changelog.title")} - +
@@ -122,7 +122,8 @@ export default function Changelog() {

- {i18n.t("changelog.empty")} {i18n.t("changelog.viewJson")} + {i18n.t("changelog.empty")}{" "} + {i18n.t("changelog.viewJson")}

diff --git a/packages/console/app/src/routes/docs/[...path].ts b/packages/console/app/src/routes/docs/[...path].ts index 5493c31a62f..0711b5ce0ff 100644 --- a/packages/console/app/src/routes/docs/[...path].ts +++ b/packages/console/app/src/routes/docs/[...path].ts @@ -1,5 +1,5 @@ import type { APIEvent } from "@solidjs/start/server" -import { localeFromCookieHeader, tag } from "~/lib/language" +import { LOCALE_HEADER, localeFromCookieHeader, parseLocale, tag } from "~/lib/language" async function handler(evt: APIEvent) { const req = evt.request.clone() @@ -7,7 +7,7 @@ async function handler(evt: APIEvent) { const targetUrl = `https://docs.opencode.ai${url.pathname}${url.search}` const headers = new Headers(req.headers) - const locale = localeFromCookieHeader(req.headers.get("cookie")) + const locale = parseLocale(req.headers.get(LOCALE_HEADER)) ?? localeFromCookieHeader(req.headers.get("cookie")) if (locale) headers.set("accept-language", tag(locale)) const response = await fetch(targetUrl, { diff --git a/packages/console/app/src/routes/docs/index.ts b/packages/console/app/src/routes/docs/index.ts index 5493c31a62f..0711b5ce0ff 100644 --- a/packages/console/app/src/routes/docs/index.ts +++ b/packages/console/app/src/routes/docs/index.ts @@ -1,5 +1,5 @@ import type { APIEvent } from "@solidjs/start/server" -import { localeFromCookieHeader, tag } from "~/lib/language" +import { LOCALE_HEADER, localeFromCookieHeader, parseLocale, tag } from "~/lib/language" async function handler(evt: APIEvent) { const req = evt.request.clone() @@ -7,7 +7,7 @@ async function handler(evt: APIEvent) { const targetUrl = `https://docs.opencode.ai${url.pathname}${url.search}` const headers = new Headers(req.headers) - const locale = localeFromCookieHeader(req.headers.get("cookie")) + const locale = parseLocale(req.headers.get(LOCALE_HEADER)) ?? localeFromCookieHeader(req.headers.get("cookie")) if (locale) headers.set("accept-language", tag(locale)) const response = await fetch(targetUrl, { diff --git a/packages/console/app/src/routes/download/index.tsx b/packages/console/app/src/routes/download/index.tsx index 0c89e4abdc0..b5dbbd39a9a 100644 --- a/packages/console/app/src/routes/download/index.tsx +++ b/packages/console/app/src/routes/download/index.tsx @@ -1,5 +1,5 @@ import "./index.css" -import { Title, Meta, Link } from "@solidjs/meta" +import { Title, Meta } from "@solidjs/meta" import { A, createAsync, query } from "@solidjs/router" import { Header } from "~/component/header" import { Footer } from "~/component/footer" @@ -11,6 +11,8 @@ import { config } from "~/config" import { createSignal, onMount, Show, JSX } from "solid-js" import { DownloadPlatform } from "./types" import { useI18n } from "~/context/i18n" +import { useLanguage } from "~/context/language" +import { LocaleLinks } from "~/component/locale-links" type OS = "macOS" | "Windows" | "Linux" | null @@ -66,6 +68,7 @@ function CopyStatus() { export default function Download() { const i18n = useI18n() + const language = useLanguage() const [detectedOS, setDetectedOS] = createSignal(null) onMount(() => { @@ -83,7 +86,7 @@ export default function Download() { return (
{i18n.t("download.title")} - +
@@ -97,7 +100,10 @@ export default function Download() {

{i18n.t("download.hero.title")}

{i18n.t("download.hero.subtitle")}

- + {i18n.t("download.hero.button", { os: detectedOS()! })} @@ -169,7 +175,7 @@ export default function Download() { {i18n.t("download.platform.macosAppleSilicon")}
- + {i18n.t("download.action.download")}
@@ -185,7 +191,7 @@ export default function Download() { {i18n.t("download.platform.macosIntel")}
- + {i18n.t("download.action.download")} @@ -208,7 +214,7 @@ export default function Download() { {i18n.t("download.platform.windowsX64")} - + {i18n.t("download.action.download")} @@ -224,7 +230,7 @@ export default function Download() { {i18n.t("download.platform.linuxDeb")} - + {i18n.t("download.action.download")} @@ -240,7 +246,7 @@ export default function Download() { {i18n.t("download.platform.linuxRpm")} - + {i18n.t("download.action.download")} @@ -257,7 +263,7 @@ export default function Download() { Linux (.AppImage) - + Download */} @@ -422,36 +428,38 @@ export default function Download() {
  • - {i18n.t("home.faq.a2.before")} {i18n.t("home.faq.a2.link")}. + {i18n.t("home.faq.a2.before")} {i18n.t("home.faq.a2.link")}.
  • {i18n.t("download.faq.a3.beforeLocal")}{" "} - + {i18n.t("download.faq.a3.localLink")} {" "} - {i18n.t("download.faq.a3.afterLocal.beforeZen")} {i18n.t("nav.zen")} + {i18n.t("download.faq.a3.afterLocal.beforeZen")}{" "} + {i18n.t("nav.zen")} {i18n.t("download.faq.a3.afterZen")}
  • - {i18n.t("home.faq.a5.beforeDesktop")} {i18n.t("home.faq.a5.desktop")}{" "} - {i18n.t("home.faq.a5.and")} {i18n.t("home.faq.a5.web")}! + {i18n.t("home.faq.a5.beforeDesktop")}{" "} + {i18n.t("home.faq.a5.desktop")} {i18n.t("home.faq.a5.and")}{" "} + {i18n.t("home.faq.a5.web")}!
  • {i18n.t("download.faq.a5.p1")} {i18n.t("download.faq.a5.p2.beforeZen")}{" "} - {i18n.t("nav.zen")} + {i18n.t("nav.zen")} {i18n.t("download.faq.a5.p2.afterZen")}
  • {i18n.t("download.faq.a6.p1")} {i18n.t("download.faq.a6.p2.beforeShare")}{" "} - {i18n.t("download.faq.a6.shareLink")}. + {i18n.t("download.faq.a6.shareLink")}.
  • diff --git a/packages/console/app/src/routes/enterprise/index.tsx b/packages/console/app/src/routes/enterprise/index.tsx index c9f48749088..ee323ff8260 100644 --- a/packages/console/app/src/routes/enterprise/index.tsx +++ b/packages/console/app/src/routes/enterprise/index.tsx @@ -1,12 +1,12 @@ import "./index.css" -import { Title, Meta, Link } from "@solidjs/meta" +import { Title, Meta } from "@solidjs/meta" import { createSignal, Show } from "solid-js" -import { config } from "~/config" import { Header } from "~/component/header" import { Footer } from "~/component/footer" import { Legal } from "~/component/legal" import { Faq } from "~/component/faq" import { useI18n } from "~/context/i18n" +import { LocaleLinks } from "~/component/locale-links" export default function Enterprise() { const i18n = useI18n() @@ -57,7 +57,7 @@ export default function Enterprise() { return (
    {i18n.t("enterprise.title")} - +
    diff --git a/packages/console/app/src/routes/index.tsx b/packages/console/app/src/routes/index.tsx index a56b2ac62da..e47134d2b94 100644 --- a/packages/console/app/src/routes/index.tsx +++ b/packages/console/app/src/routes/index.tsx @@ -1,5 +1,5 @@ import "./index.css" -import { Title, Meta, Link } from "@solidjs/meta" +import { Title, Meta } from "@solidjs/meta" //import { HttpHeader } from "@solidjs/start" import video from "../asset/lander/opencode-min.mp4" import videoPoster from "../asset/lander/opencode-poster.png" @@ -15,6 +15,8 @@ import { github } from "~/lib/github" import { createMemo } from "solid-js" import { config } from "~/config" import { useI18n } from "~/context/i18n" +import { useLanguage } from "~/context/language" +import { LocaleLinks } from "~/component/locale-links" function CopyStatus() { return ( @@ -27,6 +29,7 @@ function CopyStatus() { export default function Home() { const i18n = useI18n() + const language = useLanguage() const githubData = createAsync(() => github()) const release = createMemo(() => githubData()?.release) @@ -46,7 +49,7 @@ export default function Home() {
    {/**/} {i18n.t("home.title")} - +
    @@ -61,10 +64,10 @@ export default function Home() { {i18n.t("home.banner.text")} {i18n.t("home.banner.platforms")}. - + {i18n.t("home.banner.downloadNow")} - + {i18n.t("home.banner.downloadBetaNow")}
    @@ -217,7 +220,7 @@ export default function Home() {
  • - + {i18n.t("home.what.readDocs")} {i18n.t("home.privacy.body")} {i18n.t("home.privacy.learnMore")}{" "} - {i18n.t("home.privacy.link")}. + {i18n.t("home.privacy.link")}.

    @@ -673,14 +676,15 @@ export default function Home() {
  • - {i18n.t("home.faq.a2.before")} {i18n.t("home.faq.a2.link")}. + {i18n.t("home.faq.a2.before")} {i18n.t("home.faq.a2.link")}.
  • - {i18n.t("home.faq.a3.p1")} {i18n.t("home.faq.a3.p2.beforeZen")} {i18n.t("nav.zen")} + {i18n.t("home.faq.a3.p1")} {i18n.t("home.faq.a3.p2.beforeZen")}{" "} + {i18n.t("nav.zen")} {i18n.t("home.faq.a3.p2.afterZen")} {i18n.t("home.faq.a3.p3")} {i18n.t("home.faq.a3.p4.beforeLocal")}{" "} - + {i18n.t("home.faq.a3.p4.localLink")} . @@ -688,13 +692,15 @@ export default function Home() {
  • - {i18n.t("home.faq.a4.p1")} {i18n.t("common.learnMore")}. + {i18n.t("home.faq.a4.p1")}{" "} + {i18n.t("common.learnMore")}.
  • - {i18n.t("home.faq.a5.beforeDesktop")} {i18n.t("home.faq.a5.desktop")}{" "} - {i18n.t("home.faq.a5.and")} {i18n.t("home.faq.a5.web")}! + {i18n.t("home.faq.a5.beforeDesktop")}{" "} + {i18n.t("home.faq.a5.desktop")} {i18n.t("home.faq.a5.and")}{" "} + {i18n.t("home.faq.a5.web")}!
  • @@ -703,8 +709,9 @@ export default function Home() {
  • {i18n.t("home.faq.a7.p1")} {i18n.t("home.faq.a7.p2.beforeModels")}{" "} - {i18n.t("home.faq.a7.p2.modelsLink")} {i18n.t("home.faq.a7.p2.and")}{" "} - {i18n.t("home.faq.a7.p2.shareLink")}. + {i18n.t("home.faq.a7.p2.modelsLink")}{" "} + {i18n.t("home.faq.a7.p2.and")}{" "} + {i18n.t("home.faq.a7.p2.shareLink")}.
  • @@ -808,7 +815,7 @@ export default function Home() { - + {i18n.t("home.zenCta.link")} OpenCode | Privacy Policy - +
    @@ -33,9 +35,9 @@ export default function PrivacyPolicy() {

    Remember that your use of OpenCode is at all times subject to our Terms of Use,{" "} - https://opencode.ai/legal/terms-of-service, which incorporates - this Privacy Policy. Any terms we use in this Policy without defining them have the definitions given to - them in the Terms of Use. + https://opencode.ai/legal/terms-of-service, + which incorporates this Privacy Policy. Any terms we use in this Policy without defining them have the + definitions given to them in the Terms of Use.

    You may print a copy of this Privacy Policy by clicking the print button in your browser.

    diff --git a/packages/console/app/src/routes/legal/terms-of-service/index.tsx b/packages/console/app/src/routes/legal/terms-of-service/index.tsx index f0d7be61c06..f770aa7a067 100644 --- a/packages/console/app/src/routes/legal/terms-of-service/index.tsx +++ b/packages/console/app/src/routes/legal/terms-of-service/index.tsx @@ -1,16 +1,18 @@ import "../../brand/index.css" import "./index.css" -import { Title, Meta, Link } from "@solidjs/meta" +import { Title, Meta } from "@solidjs/meta" import { Header } from "~/component/header" -import { config } from "~/config" import { Footer } from "~/component/footer" import { Legal } from "~/component/legal" +import { LocaleLinks } from "~/component/locale-links" +import { useLanguage } from "~/context/language" export default function TermsOfService() { + const language = useLanguage() return (
    OpenCode | Terms of Service - +
    @@ -36,7 +38,7 @@ export default function TermsOfService() { ANOMALY INNOVATIONS, INC. ("OpenCode," "we" and "us"). Your use of the Services in any way means that you agree to all of these Terms, and these Terms will remain in effect while you use the Services. These Terms include the provisions in this document as well as those in the Privacy Policy{" "} - https://opencode.ai/legal/privacy-policy.{" "} + https://opencode.ai/legal/privacy-policy.{" "} Your use of or participation in certain Services may also be subject to additional policies, rules and/or conditions ("Additional Terms"), which are incorporated herein by reference, and you understand @@ -259,9 +261,10 @@ export default function TermsOfService() {

    Paid Services

    Certain of our Services, including Zen, may be subject to payments now or in the future (the "Paid - Services"). Please see our Paid Services page https://opencode.ai/zen for a - description of the current Paid Services. Please note that any payment terms presented to you in the - process of using or signing up for a Paid Service are deemed part of these Terms. + Services"). Please see our Paid Services page{" "} + https://opencode.ai/zen for a description of the current Paid + Services. Please note that any payment terms presented to you in the process of using or signing up for + a Paid Service are deemed part of these Terms.

    Billing

    @@ -315,9 +318,9 @@ export default function TermsOfService() {

    What if I want to stop using the Services?

    You're free to do that at any time; please refer to our Privacy Policy{" "} - https://opencode.ai/legal/privacy-policy, as well as the licenses - above, to understand how we treat information you provide to us after you have stopped using our - Services. + https://opencode.ai/legal/privacy-policy, as well + as the licenses above, to understand how we treat information you provide to us after you have stopped + using our Services.

    diff --git a/packages/console/app/src/routes/s/[id].ts b/packages/console/app/src/routes/s/[id].ts index 3cdc486a4a6..628a75b2e3c 100644 --- a/packages/console/app/src/routes/s/[id].ts +++ b/packages/console/app/src/routes/s/[id].ts @@ -1,5 +1,5 @@ import type { APIEvent } from "@solidjs/start/server" -import { localeFromCookieHeader, tag } from "~/lib/language" +import { LOCALE_HEADER, localeFromCookieHeader, parseLocale, tag } from "~/lib/language" async function handler(evt: APIEvent) { const req = evt.request.clone() @@ -7,7 +7,7 @@ async function handler(evt: APIEvent) { const targetUrl = `https://docs.opencode.ai/docs${url.pathname}${url.search}` const headers = new Headers(req.headers) - const locale = localeFromCookieHeader(req.headers.get("cookie")) + const locale = parseLocale(req.headers.get(LOCALE_HEADER)) ?? localeFromCookieHeader(req.headers.get("cookie")) if (locale) headers.set("accept-language", tag(locale)) const response = await fetch(targetUrl, { diff --git a/packages/console/app/src/routes/t/[...path].tsx b/packages/console/app/src/routes/t/[...path].tsx index 5cb412f7890..3f65c6822ab 100644 --- a/packages/console/app/src/routes/t/[...path].tsx +++ b/packages/console/app/src/routes/t/[...path].tsx @@ -1,5 +1,5 @@ import type { APIEvent } from "@solidjs/start/server" -import { localeFromCookieHeader, tag } from "~/lib/language" +import { LOCALE_HEADER, localeFromCookieHeader, parseLocale, tag } from "~/lib/language" async function handler(evt: APIEvent) { const req = evt.request.clone() @@ -7,7 +7,7 @@ async function handler(evt: APIEvent) { const targetUrl = `https://enterprise.opencode.ai/${url.pathname}${url.search}` const headers = new Headers(req.headers) - const locale = localeFromCookieHeader(req.headers.get("cookie")) + const locale = parseLocale(req.headers.get(LOCALE_HEADER)) ?? localeFromCookieHeader(req.headers.get("cookie")) if (locale) headers.set("accept-language", tag(locale)) const response = await fetch(targetUrl, { diff --git a/packages/console/app/src/routes/temp.tsx b/packages/console/app/src/routes/temp.tsx index d6d89047938..0a2447f44e3 100644 --- a/packages/console/app/src/routes/temp.tsx +++ b/packages/console/app/src/routes/temp.tsx @@ -6,6 +6,7 @@ import logoDark from "../asset/logo-ornate-dark.svg" import IMG_SPLASH from "../asset/lander/screenshot-splash.png" import { IconCopy, IconCheck } from "../component/icon" import { useI18n } from "~/context/i18n" +import { useLanguage } from "~/context/language" function CopyStatus() { return ( @@ -18,6 +19,7 @@ function CopyStatus() { export default function Home() { const i18n = useI18n() + const language = useLanguage() onMount(() => { const commands = document.querySelectorAll("[data-copy]") @@ -49,16 +51,16 @@ export default function Home() { opencode logo dark

    {i18n.t("temp.hero.title")}

  • {i18n.t("temp.zen")} {i18n.t("temp.feature.zen.beforeLink")}{" "} - {i18n.t("temp.feature.zen.link")} {i18n.t("temp.feature.zen.afterLink")}{" "} - + {i18n.t("temp.feature.zen.link")}{" "} + {i18n.t("temp.feature.zen.afterLink")}
  • {i18n.t("home.what.multiSession.title")} {i18n.t("home.what.multiSession.body")} @@ -148,7 +150,7 @@ export default function Home() {
    {i18n.t("temp.screenshot.caption")}
    - + {i18n.t("temp.screenshot.alt")}
    diff --git a/packages/console/app/src/routes/user-menu.tsx b/packages/console/app/src/routes/user-menu.tsx index f089aad8173..fa1c1f60bb1 100644 --- a/packages/console/app/src/routes/user-menu.tsx +++ b/packages/console/app/src/routes/user-menu.tsx @@ -3,6 +3,7 @@ import { getRequestEvent } from "solid-js/web" import { useAuthSession } from "~/context/auth" import { Dropdown } from "~/component/dropdown" import { useI18n } from "~/context/i18n" +import { useLanguage } from "~/context/language" import "./user-menu.css" const logout = action(async () => { @@ -22,10 +23,11 @@ const logout = action(async () => { export function UserMenu(props: { email: string | null | undefined }) { const i18n = useI18n() + const language = useLanguage() return (
    - + {i18n.t("user.logout")} diff --git a/packages/console/app/src/routes/workspace.tsx b/packages/console/app/src/routes/workspace.tsx index d7117a7d220..10e503ac526 100644 --- a/packages/console/app/src/routes/workspace.tsx +++ b/packages/console/app/src/routes/workspace.tsx @@ -6,6 +6,7 @@ import { UserMenu } from "./user-menu" import { withActor } from "~/context/auth.withActor" import { User } from "@opencode-ai/console-core/user.js" import { Actor } from "@opencode-ai/console-core/actor.js" +import { useLanguage } from "~/context/language" const getUserEmail = query(async (workspaceID: string) => { "use server" @@ -18,12 +19,13 @@ const getUserEmail = query(async (workspaceID: string) => { export default function WorkspaceLayout(props: RouteSectionProps) { const params = useParams() + const language = useLanguage() const userEmail = createAsync(() => getUserEmail(params.id!)) return (
    - + diff --git a/packages/console/app/src/routes/workspace/[id]/members/member-section.tsx b/packages/console/app/src/routes/workspace/[id]/members/member-section.tsx index dce23a496c3..5a440632f8a 100644 --- a/packages/console/app/src/routes/workspace/[id]/members/member-section.tsx +++ b/packages/console/app/src/routes/workspace/[id]/members/member-section.tsx @@ -8,6 +8,7 @@ import { Actor } from "@opencode-ai/console-core/actor.js" import { User } from "@opencode-ai/console-core/user.js" import { RoleDropdown } from "./role-dropdown" import { useI18n } from "~/context/i18n" +import { useLanguage } from "~/context/language" import { formError, localizeError } from "~/lib/form-error" const listMembers = query(async (workspaceID: string) => { @@ -218,6 +219,7 @@ function MemberRow(props: { export function MemberSection() { const params = useParams() const i18n = useI18n() + const language = useLanguage() const data = createAsync(() => listMembers(params.id!)) const submission = useSubmission(inviteMember) const [store, setStore] = createStore({ @@ -277,7 +279,7 @@ export function MemberSection() {
    {i18n.t("workspace.members.beta.beforeLink")}{" "} - + {i18n.t("common.learnMore")} . diff --git a/packages/console/app/src/routes/workspace/[id]/model-section.tsx b/packages/console/app/src/routes/workspace/[id]/model-section.tsx index d67c72b5623..97f95278a16 100644 --- a/packages/console/app/src/routes/workspace/[id]/model-section.tsx +++ b/packages/console/app/src/routes/workspace/[id]/model-section.tsx @@ -17,6 +17,7 @@ import { IconZai, } from "~/component/icon" import { useI18n } from "~/context/i18n" +import { useLanguage } from "~/context/language" import { formError } from "~/lib/form-error" const getModelLab = (modelId: string) => { @@ -80,6 +81,7 @@ const updateModel = action(async (form: FormData) => { export function ModelSection() { const params = useParams() const i18n = useI18n() + const language = useLanguage() const modelsInfo = createAsync(() => getModelsInfo(params.id!)) const userInfo = createAsync(() => querySessionInfo(params.id!)) @@ -96,8 +98,8 @@ export function ModelSection() {

    {i18n.t("workspace.models.title")}

    - {i18n.t("workspace.models.subtitle.beforeLink")} {i18n.t("common.learnMore")} - . + {i18n.t("workspace.models.subtitle.beforeLink")}{" "} + {i18n.t("common.learnMore")}.

    diff --git a/packages/console/app/src/routes/zen/index.tsx b/packages/console/app/src/routes/zen/index.tsx index 50a818e0d20..d32c1bbaaf2 100644 --- a/packages/console/app/src/routes/zen/index.tsx +++ b/packages/console/app/src/routes/zen/index.tsx @@ -1,9 +1,8 @@ import "./index.css" import { createAsync, query, redirect } from "@solidjs/router" -import { Title, Meta, Link } from "@solidjs/meta" +import { Title, Meta } from "@solidjs/meta" //import { HttpHeader } from "@solidjs/start" import zenLogoLight from "../../asset/zen-ornate-light.svg" -import { config } from "~/config" import zenLogoDark from "../../asset/zen-ornate-dark.svg" import compareVideo from "../../asset/lander/opencode-comparison-min.mp4" import compareVideoPoster from "../../asset/lander/opencode-comparison-poster.png" @@ -20,6 +19,8 @@ import { Header } from "~/component/header" import { getLastSeenWorkspaceID } from "../workspace/common" import { IconGemini, IconMiniMax, IconZai } from "~/component/icon" import { useI18n } from "~/context/i18n" +import { useLanguage } from "~/context/language" +import { LocaleLinks } from "~/component/locale-links" const checkLoggedIn = query(async () => { "use server" @@ -30,11 +31,12 @@ const checkLoggedIn = query(async () => { export default function Home() { const loggedin = createAsync(() => checkLoggedIn()) const i18n = useI18n() + const language = useLanguage() return (
    {/**/} {i18n.t("zen.title")} - + @@ -120,7 +122,7 @@ export default function Home() {
    - + {i18n.t("zen.cta.start")} [1] @@ -184,7 +186,8 @@ export default function Home() { [2]
    {i18n.t("zen.how.step2.title")} -{" "} - {i18n.t("zen.how.step2.link")} {i18n.t("zen.how.step2.afterLink")} + {i18n.t("zen.how.step2.link")}{" "} + {i18n.t("zen.how.step2.afterLink")}
  • @@ -203,7 +206,7 @@ export default function Home() { [*]

    {i18n.t("zen.privacy.beforeExceptions")}{" "} - {i18n.t("zen.privacy.exceptionsLink")}. + {i18n.t("zen.privacy.exceptionsLink")}.

    @@ -299,15 +302,15 @@ export default function Home() {
  • {i18n.t("zen.faq.a4.p1.beforePricing")}{" "} - {i18n.t("zen.faq.a4.p1.pricingLink")}{" "} + {i18n.t("zen.faq.a4.p1.pricingLink")}{" "} {i18n.t("zen.faq.a4.p1.afterPricing")} {i18n.t("zen.faq.a4.p2.beforeAccount")}{" "} - {i18n.t("zen.faq.a4.p2.accountLink")}. {i18n.t("zen.faq.a4.p3")} + {i18n.t("zen.faq.a4.p2.accountLink")}. {i18n.t("zen.faq.a4.p3")}
  • {i18n.t("zen.faq.a5.beforeExceptions")}{" "} - {i18n.t("zen.faq.a5.exceptionsLink")}. + {i18n.t("zen.faq.a5.exceptionsLink")}.
  • diff --git a/packages/console/app/vite.config.ts b/packages/console/app/vite.config.ts index 3b013e99011..951c9a4276c 100644 --- a/packages/console/app/vite.config.ts +++ b/packages/console/app/vite.config.ts @@ -4,7 +4,9 @@ import { nitro } from "nitro/vite" export default defineConfig({ plugins: [ - solidStart() as PluginOption, + solidStart({ + middleware: "./src/middleware.ts", + }) as PluginOption, nitro({ compatibilityDate: "2024-09-19", preset: "cloudflare_module",