diff --git a/web/app/(legal)/eula/page.tsx b/web/app/[locale]/(legal)/eula/page.tsx similarity index 99% rename from web/app/(legal)/eula/page.tsx rename to web/app/[locale]/(legal)/eula/page.tsx index 114f32bb..85676b2d 100644 --- a/web/app/(legal)/eula/page.tsx +++ b/web/app/[locale]/(legal)/eula/page.tsx @@ -8,7 +8,7 @@ export const metadata: Metadata = { export default function EulaPage() { return ( <> -

End-User License Agreement

+

EULA

Last updated: December 2, 2025

diff --git a/web/app/(legal)/layout.tsx b/web/app/[locale]/(legal)/layout.tsx similarity index 100% rename from web/app/(legal)/layout.tsx rename to web/app/[locale]/(legal)/layout.tsx diff --git a/web/app/(legal)/privacy-policy/page.tsx b/web/app/[locale]/(legal)/privacy-policy/page.tsx similarity index 97% rename from web/app/(legal)/privacy-policy/page.tsx rename to web/app/[locale]/(legal)/privacy-policy/page.tsx index 982b07f6..fc945d36 100644 --- a/web/app/(legal)/privacy-policy/page.tsx +++ b/web/app/[locale]/(legal)/privacy-policy/page.tsx @@ -1,4 +1,5 @@ import type { Metadata } from "next"; +import { Link } from "../../../../i18n/navigation"; export const metadata: Metadata = { title: "Privacy Policy — cmux", @@ -29,7 +30,7 @@ export default function PrivacyPolicyPage() {

By using our Service, you accept this Privacy Policy and our{" "} - Terms of Service, and you consent to + Terms of Service, and you consent to our collection, storage, use and disclosure of your information as described here.

diff --git a/web/app/(legal)/terms-of-service/page.tsx b/web/app/[locale]/(legal)/terms-of-service/page.tsx similarity index 100% rename from web/app/(legal)/terms-of-service/page.tsx rename to web/app/[locale]/(legal)/terms-of-service/page.tsx diff --git a/web/app/assets/images.d.ts b/web/app/[locale]/assets/images.d.ts similarity index 100% rename from web/app/assets/images.d.ts rename to web/app/[locale]/assets/images.d.ts diff --git a/web/app/assets/landing-image.png b/web/app/[locale]/assets/landing-image.png similarity index 100% rename from web/app/assets/landing-image.png rename to web/app/[locale]/assets/landing-image.png diff --git a/web/app/[locale]/blog/cmd-shift-u/page.tsx b/web/app/[locale]/blog/cmd-shift-u/page.tsx new file mode 100644 index 00000000..815d4790 --- /dev/null +++ b/web/app/[locale]/blog/cmd-shift-u/page.tsx @@ -0,0 +1,74 @@ +import { useTranslations } from "next-intl"; +import { getTranslations } from "next-intl/server"; +import { Link } from "../../../../i18n/navigation"; + +export async function generateMetadata({ params }: { params: Promise<{ locale: string }> }) { + const { locale } = await params; + const t = await getTranslations({ locale, namespace: "blog.cmdShiftU" }); + const url = locale === "en" ? "/blog/cmd-shift-u" : `/${locale}/blog/cmd-shift-u`; + return { + title: t("metaTitle"), + description: t("metaDescription"), + keywords: [ + "cmux", "terminal", "macOS", "notifications", "AI coding agents", + "keyboard shortcuts", "developer tools", "workflow", + ], + openGraph: { + title: t("metaTitle"), + description: t("metaDescription"), + type: "article", + publishedTime: "2026-03-04T00:00:00Z", + url, + }, + twitter: { + card: "summary", + title: t("metaTitle"), + description: t("metaDescription"), + }, + alternates: { canonical: url }, + }; +} + +export default function CmdShiftUPage() { + const t = useTranslations("blog.posts.cmdShiftU"); + const tc = useTranslations("common"); + + return ( + <> +
+ + ← {tc("backToBlog")} + +
+ +

{t("title")}

+ + +

{t("p1")}

+ +