diff --git a/apps/web-roo-code/src/app/enterprise/page.tsx b/apps/web-roo-code/src/app/enterprise/page.tsx index ca15857ffd..7a1d36f068 100644 --- a/apps/web-roo-code/src/app/enterprise/page.tsx +++ b/apps/web-roo-code/src/app/enterprise/page.tsx @@ -5,6 +5,54 @@ import { AnimatedText } from "@/components/animated-text" import { AnimatedBackground } from "@/components/homepage" import { ContactForm } from "@/components/enterprise/contact-form" import { EXTERNAL_LINKS } from "@/lib/constants" +import type { Metadata } from "next" +import { SEO } from "@/lib/seo" + +const TITLE = "Enterprise Solution" +const DESCRIPTION = + "The control-plane for AI-powered software development. Gain visibility, governance, and control over your AI coding initiatives." +const PATH = "/enterprise" +const OG_IMAGE = SEO.ogImage + +export const metadata: Metadata = { + title: TITLE, + description: DESCRIPTION, + alternates: { + canonical: `${SEO.url}${PATH}`, + }, + openGraph: { + title: TITLE, + description: DESCRIPTION, + url: `${SEO.url}${PATH}`, + siteName: SEO.name, + images: [ + { + url: OG_IMAGE.url, + width: OG_IMAGE.width, + height: OG_IMAGE.height, + alt: OG_IMAGE.alt, + }, + ], + locale: SEO.locale, + type: "website", + }, + twitter: { + card: SEO.twitterCard, + title: TITLE, + description: DESCRIPTION, + images: [OG_IMAGE.url], + }, + keywords: [ + ...SEO.keywords, + "Enterprise AI", + "AI governance", + "AI control-plane", + "developer productivity", + "SAML", + "SCIM", + "cost management", + ], +} export default async function Enterprise() { return ( diff --git a/apps/web-roo-code/src/app/evals/page.tsx b/apps/web-roo-code/src/app/evals/page.tsx index b97b025348..a6af30d70e 100644 --- a/apps/web-roo-code/src/app/evals/page.tsx +++ b/apps/web-roo-code/src/app/evals/page.tsx @@ -1,25 +1,45 @@ import type { Metadata } from "next" import { getEvalRuns } from "@/actions/evals" +import { SEO } from "@/lib/seo" import { Evals } from "./evals" export const revalidate = 300 export const dynamic = "force-dynamic" +const TITLE = "Evals" +const DESCRIPTION = "Explore quantitative evals of LLM coding skills across tasks and providers." +const PATH = "/evals" +const IMAGE = { + url: "https://i.imgur.com/ijP7aZm.png", + width: 1954, + height: 1088, + alt: "Roo Code Evals – LLM coding benchmarks", +} + export const metadata: Metadata = { - title: "Roo Code Evals", + title: TITLE, + description: DESCRIPTION, + alternates: { + canonical: `${SEO.url}${PATH}`, + }, openGraph: { - title: "Roo Code Evals", - description: "Quantitative evals of LLM coding skills.", - url: "https://roocode.com/evals", - siteName: "Roo Code", - images: { - url: "https://i.imgur.com/ijP7aZm.png", - width: 1954, - height: 1088, - }, + title: TITLE, + description: DESCRIPTION, + url: `${SEO.url}${PATH}`, + siteName: SEO.name, + images: [IMAGE], + locale: SEO.locale, + type: "website", + }, + twitter: { + card: SEO.twitterCard, + title: TITLE, + description: DESCRIPTION, + images: [IMAGE.url], }, + keywords: [...SEO.keywords, "benchmarks", "LLM evals", "coding evaluations", "model comparison"], } export default async function Page() { diff --git a/apps/web-roo-code/src/app/layout.tsx b/apps/web-roo-code/src/app/layout.tsx index 132a8b31d7..ac33c8920f 100644 --- a/apps/web-roo-code/src/app/layout.tsx +++ b/apps/web-roo-code/src/app/layout.tsx @@ -2,6 +2,7 @@ import React from "react" import type { Metadata } from "next" import { Inter } from "next/font/google" import Script from "next/script" +import { SEO } from "@/lib/seo" import { Providers } from "@/components/providers" @@ -12,11 +13,14 @@ import "./globals.css" const inter = Inter({ subsets: ["latin"] }) export const metadata: Metadata = { - title: "Roo Code – Your AI-Powered Dev Team in VS Code", - description: - "Roo Code puts an entire AI dev team right in your editor, outpacing closed tools with deep project-wide context, multi-step agentic coding, and unmatched developer-centric flexibility.", + metadataBase: new URL(SEO.url), + title: { + template: "%s | Roo Code", + default: SEO.title, + }, + description: SEO.description, alternates: { - canonical: "https://roocode.com", + canonical: SEO.url, }, icons: { icon: [ @@ -40,6 +44,42 @@ export const metadata: Metadata = { }, ], }, + openGraph: { + title: SEO.title, + description: SEO.description, + url: SEO.url, + siteName: SEO.name, + images: [ + { + url: SEO.ogImage.url, + width: SEO.ogImage.width, + height: SEO.ogImage.height, + alt: SEO.ogImage.alt, + }, + ], + locale: SEO.locale, + type: "website", + }, + twitter: { + card: SEO.twitterCard, + title: SEO.title, + description: SEO.description, + images: [SEO.ogImage.url], + }, + robots: { + index: true, + follow: true, + googleBot: { + index: true, + follow: true, + "max-snippet": -1, + "max-image-preview": "large", + "max-video-preview": -1, + }, + }, + keywords: [...SEO.keywords], + applicationName: SEO.name, + category: SEO.category, } export default function RootLayout({ children }: { children: React.ReactNode }) { @@ -64,8 +104,8 @@ export default function RootLayout({ children }: { children: React.ReactNode }) `}
- - + +
{children} diff --git a/apps/web-roo-code/src/app/privacy/page.tsx b/apps/web-roo-code/src/app/privacy/page.tsx index ea12094ebb..1812d18eff 100644 --- a/apps/web-roo-code/src/app/privacy/page.tsx +++ b/apps/web-roo-code/src/app/privacy/page.tsx @@ -1,9 +1,41 @@ -import { Metadata } from "next" +import type { Metadata } from "next" +import { SEO } from "@/lib/seo" + +const TITLE = "Privacy Policy" +const DESCRIPTION = + "Privacy policy for Roo Code Cloud and marketing website. Learn how we handle your data and protect your privacy." +const PATH = "/privacy" +const OG_IMAGE = SEO.ogImage export const metadata: Metadata = { - title: "Privacy Policy - Roo Code", - description: - "Privacy policy for Roo Code Cloud and marketing website. Learn how we handle your data and protect your privacy.", + title: TITLE, + description: DESCRIPTION, + alternates: { + canonical: `${SEO.url}${PATH}`, + }, + openGraph: { + title: TITLE, + description: DESCRIPTION, + url: `${SEO.url}${PATH}`, + siteName: SEO.name, + images: [ + { + url: OG_IMAGE.url, + width: OG_IMAGE.width, + height: OG_IMAGE.height, + alt: OG_IMAGE.alt, + }, + ], + locale: SEO.locale, + type: "article", + }, + twitter: { + card: SEO.twitterCard, + title: TITLE, + description: DESCRIPTION, + images: [OG_IMAGE.url], + }, + keywords: [...SEO.keywords, "privacy", "data protection", "GDPR", "security"], } export default function Privacy() { diff --git a/apps/web-roo-code/src/app/robots.ts b/apps/web-roo-code/src/app/robots.ts new file mode 100644 index 0000000000..fcdda5031e --- /dev/null +++ b/apps/web-roo-code/src/app/robots.ts @@ -0,0 +1,13 @@ +import type { MetadataRoute } from "next" +import { SEO } from "@/lib/seo" + +export default function robots(): MetadataRoute.Robots { + return { + rules: { + userAgent: "*", + allow: "/", + }, + sitemap: `${SEO.url}/sitemap.xml`, + host: SEO.url, + } +} diff --git a/apps/web-roo-code/src/app/terms/page.tsx b/apps/web-roo-code/src/app/terms/page.tsx index 545e577457..f5aea3d663 100644 --- a/apps/web-roo-code/src/app/terms/page.tsx +++ b/apps/web-roo-code/src/app/terms/page.tsx @@ -1,9 +1,41 @@ -import { Metadata } from "next" +import type { Metadata } from "next" +import { SEO } from "@/lib/seo" + +const TITLE = "Terms of Service" +const DESCRIPTION = + "Terms of Service for Roo Code Cloud. Learn about our service terms, commercial conditions, and legal framework." +const PATH = "/terms" +const OG_IMAGE = SEO.ogImage export const metadata: Metadata = { - title: "Terms of Service - Roo Code", - description: - "Terms of Service for Roo Code Cloud. Learn about our service terms, commercial conditions, and legal framework.", + title: TITLE, + description: DESCRIPTION, + alternates: { + canonical: `${SEO.url}${PATH}`, + }, + openGraph: { + title: TITLE, + description: DESCRIPTION, + url: `${SEO.url}${PATH}`, + siteName: SEO.name, + images: [ + { + url: OG_IMAGE.url, + width: OG_IMAGE.width, + height: OG_IMAGE.height, + alt: OG_IMAGE.alt, + }, + ], + locale: SEO.locale, + type: "article", + }, + twitter: { + card: SEO.twitterCard, + title: TITLE, + description: DESCRIPTION, + images: [OG_IMAGE.url], + }, + keywords: [...SEO.keywords, "terms of service", "legal", "agreement", "subscription"], } export default function Terms() { diff --git a/apps/web-roo-code/src/lib/seo.ts b/apps/web-roo-code/src/lib/seo.ts new file mode 100644 index 0000000000..962662bb22 --- /dev/null +++ b/apps/web-roo-code/src/lib/seo.ts @@ -0,0 +1,30 @@ +const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL ?? "https://roocode.com" + +export const SEO = { + url: SITE_URL, + name: "Roo Code", + title: "Roo Code – Your AI-Powered Dev Team in VS Code", + description: + "Roo Code puts an entire AI dev team right in your editor, outpacing closed tools with deep project-wide context, multi-step agentic coding, and unmatched developer-centric flexibility.", + locale: "en_US", + ogImage: { + url: "/android-chrome-512x512.png", + width: 512, + height: 512, + alt: "Roo Code Logo", + }, + keywords: [ + "Roo Code", + "AI coding agent", + "VS Code extension", + "AI pair programmer", + "software development", + "agentic coding", + "code refactoring", + "debugging", + ], + category: "technology", + twitterCard: "summary_large_image" as const, +} as const + +export type SeoConfig = typeof SEO