feat(web): fill missing SEO-related values (#7096)

Co-authored-by: Matt Rubens <mrubens@users.noreply.github.com>
This commit is contained in:
Dicha Zelianivan Arkana 2025-08-14 23:51:13 +07:00 committed by GitHub
parent 1ee9e01d6c
commit 62d023d016
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 240 additions and 25 deletions

View file

@ -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 (

View file

@ -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",
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,
alternates: {
canonical: `${SEO.url}${PATH}`,
},
openGraph: {
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() {

View file

@ -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 })
`}
</Script>
<div itemScope itemType="https://schema.org/WebSite">
<link itemProp="url" href="https://roocode.com" />
<meta itemProp="name" content="Roo Code" />
<link itemProp="url" href={SEO.url} />
<meta itemProp="name" content={SEO.name} />
</div>
<Providers>
<Shell>{children}</Shell>

View file

@ -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() {

View file

@ -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,
}
}

View file

@ -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() {

View file

@ -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