From 8d0414bd2562bfe4b757a33ef5e7fa5a15d0c3b1 Mon Sep 17 00:00:00 2001 From: Jan Carbonell Date: Sun, 19 Apr 2026 10:31:57 -0700 Subject: [PATCH] feat(landing): SEO metadata, JSON-LD, H1 fixes, manifest (#1493) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(landing): SEO metadata, JSON-LD, H1 fixes, manifest Raises the site's traditional SEO to match its strong agent-readiness foundations (llms.txt, api-catalog, markdown negotiation). Metadata: - Root layout: canonical, og:type/siteName/locale, explicit robots - Per-page canonical + openGraph.url on every route - Rewritten titles/descriptions for /pricing, /enterprise, /den, /download (previously 14-21 char titles and 51-73 char descriptions) - /feedback and /starter-success marked noindex,follow - /feedback removed from sitemap; /privacy and /terms demoted to 0.3 - Title dash normalized to em-dash site-wide Headings: - /den gains a real

(was

only — a11y + SEO bug) - /enterprise H1 rewritten to be enterprise-specific (was a dup of home) - /pricing H1 enriched; tier names promoted to

in pricing-grid - /download nav-card duplicate H2s demoted to spans - lib/agent-markdown.ts H1s realigned with HTML for agent parity Structured data: - New components/structured-data.tsx helper - Organization on every page (root) - SoftwareApplication on / and /download - Product with three Offers on /pricing Manifest & perf: - New app/manifest.ts - Enterprise hero: 12MB PNG -> 1.1MB JPEG (1600px q70) Old PNG left in public/ for a follow-up cleanup commit * chore(landing): remove unused /den marketing page Deletes the /den route and its components (LandingDen, DenHero) along with every internal reference. The cloud product is still linked from nav + footer, pointing at https://app.openworklabs.com. - Removed from sitemap.ts, middleware.ts matcher, and agent-markdown (both the markdown twin and the "Den (team workspace)" home mention) - Removed from llms.txt routing list and site map - Footer "Cloud" link now points to the external app (matches nav) - Nav internal key renamed from "den" to "cloud" and type union updated - WebMCP navigate_to destinations no longer advertise "den" api-catalog still references "OpenWork Den API" since that's the API product name, not the marketing page — untouched. * fix(landing): point nav + footer Cloud link at /cloud redirect Previous removal of /den hardcoded the external app URL into the nav and footer. Switch to the /cloud internal path so the existing cloud redirect is the single source of truth (and works consistently with the rest of the internal links). * docs(landing): restore Cloud mentions in llms.txt and agent-markdown The previous /den removal also stripped every Cloud mention from the agent-facing text. Restore them pointing at /cloud (which redirects to https://app.openworklabs.com) so agents can still route users to the hosted workspace. * fix(landing): link Cloud directly to app.openworklabs.com, not /cloud There's no /cloud route on the marketing site — the hosted app lives at https://app.openworklabs.com. Point every Cloud link (nav, footer, llms.txt, agent-markdown, WebMCP) at the real URL. * feat(landing): replace Trust details link with Security Review CTA The old small Trust details text link under the Book a call button got lost. Surface it as a proper secondary CTA next to Book a call, and rename to Security Review to set expectations for enterprise buyers. Also updates the enterprise markdown twin to mirror the label. * fix(landing): preserve og:type/siteName/locale/images on pages overriding openGraph Next.js replaces (not merges) the openGraph object across layout/page boundaries. Earlier per-page metadata added only og:url, which silently wiped og:type, og:siteName, og:locale, and og:image off every page that did so — exactly the fields the root layout relied on for defaults. Introduce lib/seo.ts with a baseOpenGraph constant and spread it into every per-page openGraph override. Caught by running the PR's test plan against the dev server: 12 failing checks → 0 after this fix. * feat(landing): rasterize SVG into favicon.ico + PNG icon set Adds proper raster icons for browsers/OSes that don't render SVG favicons (older Safari, Android home-screen, Windows taskbar): - app/favicon.ico — 32×32, PNG-in-ICO container - app/icon.png — 192×192 - app/apple-icon.png — 180×180 Uses Next.js App Router icon-file convention — Next auto-generates the / tags, so the manual icons: metadata block in app/layout.tsx is removed. Manifest updated to advertise the 192×192 PNG (the Android PWA pick) alongside the 180 apple-icon and the SVG mark. All three PNGs generated from public/openwork-mark.svg with sharp, centered on a white square canvas with ~10% padding so the mark doesn't bleed to the edges at any size. Generator script at /tmp/generate-favicons.mjs (not committed) — re-run any time the source SVG changes. * fix(landing): match /enterprise H1 styling + copy to / The /enterprise hero H1 used slightly different Tailwind classes (mb-6, leading-[1.05]) than the homepage H1 (mb-5, leading-[1.1]), giving a visibly different type rhythm. Align to the home page classes. Copy updated to 'A privacy-first alternative to Claude Cowork for your org' — clearer positioning than 'OpenWork for the enterprise'. Mirrored in the agent-markdown enterprise twin for parity. * fix(landing): use 'organization' not 'org' in /enterprise H1 * fix(landing): restore original /enterprise hero subhead copy * fix(landing): open Docs in a new tab from the main nav Footer's Docs link already opens in a new tab; the top nav didn't. Add an explicit newTab flag to the nav items array and honor it in both the desktop and mobile menus so visitors keep the marketing tab open while reading docs. --- ee/apps/landing/app/apple-icon.png | Bin 0 -> 4236 bytes ee/apps/landing/app/den/page.tsx | 22 ------- ee/apps/landing/app/download/page.tsx | 40 ++++++++++-- ee/apps/landing/app/enterprise/page.tsx | 13 +++- ee/apps/landing/app/favicon.ico | Bin 0 -> 810 bytes ee/apps/landing/app/feedback/page.tsx | 14 ++++- ee/apps/landing/app/icon.png | Bin 0 -> 4570 bytes ee/apps/landing/app/layout.tsx | 27 ++++++-- ee/apps/landing/app/manifest.ts | 33 ++++++++++ ee/apps/landing/app/page.tsx | 49 +++++++++++++-- ee/apps/landing/app/pricing/page.tsx | 58 +++++++++++++++++- ee/apps/landing/app/privacy/page.tsx | 5 +- ee/apps/landing/app/sitemap.ts | 24 ++++---- ee/apps/landing/app/starter-success/page.tsx | 9 ++- ee/apps/landing/app/terms/page.tsx | 5 +- ee/apps/landing/app/trust/page.tsx | 10 ++- ee/apps/landing/components/den-hero.tsx | 37 ----------- ee/apps/landing/components/landing-den.tsx | 36 ----------- .../landing/components/landing-enterprise.tsx | 13 ++-- ee/apps/landing/components/landing-home.tsx | 2 +- ee/apps/landing/components/pricing-grid.tsx | 2 +- ee/apps/landing/components/site-footer.tsx | 9 ++- ee/apps/landing/components/site-nav.tsx | 13 ++-- .../landing/components/structured-data.tsx | 12 ++++ .../landing/components/webmcp-provider.tsx | 4 +- ee/apps/landing/lib/agent-markdown.ts | 33 ++-------- ee/apps/landing/lib/seo.ts | 6 ++ ee/apps/landing/middleware.ts | 2 +- .../landing/public/enterprise-showcase-bg.jpg | Bin 0 -> 1108255 bytes ee/apps/landing/public/llms.txt | 4 +- 30 files changed, 300 insertions(+), 182 deletions(-) create mode 100644 ee/apps/landing/app/apple-icon.png delete mode 100644 ee/apps/landing/app/den/page.tsx create mode 100644 ee/apps/landing/app/favicon.ico create mode 100644 ee/apps/landing/app/icon.png create mode 100644 ee/apps/landing/app/manifest.ts delete mode 100644 ee/apps/landing/components/den-hero.tsx delete mode 100644 ee/apps/landing/components/landing-den.tsx create mode 100644 ee/apps/landing/components/structured-data.tsx create mode 100644 ee/apps/landing/lib/seo.ts create mode 100644 ee/apps/landing/public/enterprise-showcase-bg.jpg diff --git a/ee/apps/landing/app/apple-icon.png b/ee/apps/landing/app/apple-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b1d86b6888cf3867ba1dab654729c4b7f605833f GIT binary patch literal 4236 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 Y_WBeYuQ#ZF`n_<*P|p-z0dtD}KhZrJEdT%j literal 0 HcmV?d00001 diff --git a/ee/apps/landing/app/den/page.tsx b/ee/apps/landing/app/den/page.tsx deleted file mode 100644 index aeb20b22..00000000 --- a/ee/apps/landing/app/den/page.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { LandingDen } from "../../components/landing-den"; -import { getGithubData } from "../../lib/github"; - -export const metadata = { - title: "OpenWork — Den", - description: - "Always-on AI workers that handle repetitive work for your team and report back in Slack, Telegram, or the desktop app.", -}; - -export default async function Den() { - const github = await getGithubData(); - const cal = process.env.NEXT_PUBLIC_CAL_URL || "/enterprise#book"; - - return ( - - ); -} diff --git a/ee/apps/landing/app/download/page.tsx b/ee/apps/landing/app/download/page.tsx index c1ec01f1..e7497dfc 100644 --- a/ee/apps/landing/app/download/page.tsx +++ b/ee/apps/landing/app/download/page.tsx @@ -1,11 +1,42 @@ import { SiteFooter } from "../../components/site-footer"; import { SiteNav } from "../../components/site-nav"; +import { StructuredData } from "../../components/structured-data"; import { getGithubData } from "../../lib/github"; +import { baseOpenGraph } from "../../lib/seo"; + +const downloadSchema = { + "@context": "https://schema.org", + "@type": "SoftwareApplication", + name: "OpenWork", + description: + "Open source Claude Cowork alternative. Desktop app for macOS, Windows, and Linux that lets teams use 50+ LLMs with their own provider keys.", + url: "https://openworklabs.com/download", + downloadUrl: "https://github.com/different-ai/openwork/releases/latest", + applicationCategory: "BusinessApplication", + operatingSystem: "macOS, Windows, Linux", + offers: { + "@type": "Offer", + price: "0", + priceCurrency: "USD" + }, + publisher: { + "@type": "Organization", + name: "OpenWork", + url: "https://openworklabs.com" + } +}; export const metadata = { - title: "OpenWork - Download", + title: "Download OpenWork — macOS, Windows, Linux", description: "Download OpenWork desktop for macOS, Windows, and Linux. Includes AUR install instructions and direct package downloads.", + alternates: { + canonical: "/download" + }, + openGraph: { + ...baseOpenGraph, + url: "https://openworklabs.com/download" + } }; export default async function Download() { @@ -15,6 +46,7 @@ export default async function Download() { return ( diff --git a/ee/apps/landing/app/enterprise/page.tsx b/ee/apps/landing/app/enterprise/page.tsx index dedc911f..8b5133ba 100644 --- a/ee/apps/landing/app/enterprise/page.tsx +++ b/ee/apps/landing/app/enterprise/page.tsx @@ -1,9 +1,18 @@ import { LandingEnterprise } from "../../components/landing-enterprise"; import { getGithubData } from "../../lib/github"; +import { baseOpenGraph } from "../../lib/seo"; export const metadata = { - title: "OpenWork — Enterprise", - description: "Secure hosting for safe, permissioned AI employees." + title: "OpenWork Enterprise — Self-hosted AI agents for teams", + description: + "Deploy shared skills, MCPs, and agent workflows across your org. Self-hosted or managed, 50+ LLM providers, HIPAA / SOC 2 / ISO 27001 / GDPR ready.", + alternates: { + canonical: "/enterprise" + }, + openGraph: { + ...baseOpenGraph, + url: "https://openworklabs.com/enterprise" + } }; export default async function Enterprise() { diff --git a/ee/apps/landing/app/favicon.ico b/ee/apps/landing/app/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c59a048ff6ea48103bc3f8bb3c5e50bb3720771e GIT binary patch literal 810 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 B6kY%T literal 0 HcmV?d00001 diff --git a/ee/apps/landing/app/layout.tsx b/ee/apps/landing/app/layout.tsx index cf7009e4..42cfbc30 100644 --- a/ee/apps/landing/app/layout.tsx +++ b/ee/apps/landing/app/layout.tsx @@ -3,6 +3,17 @@ import { Inter, JetBrains_Mono } from "next/font/google"; import Script from "next/script"; import { BotIdClient } from "botid/client"; import { WebMcpProvider } from "../components/webmcp-provider"; +import { StructuredData } from "../components/structured-data"; + +const organizationSchema = { + "@context": "https://schema.org", + "@type": "Organization", + name: "OpenWork", + legalName: "Different AI", + url: "https://openworklabs.com", + logo: "https://openworklabs.com/openwork-mark.svg", + sameAs: ["https://github.com/different-ai/openwork"] +}; const inter = Inter({ subsets: ["latin"], @@ -18,18 +29,25 @@ const jetbrains = JetBrains_Mono({ export const metadata = { metadataBase: new URL("https://openworklabs.com"), - title: "OpenWork — The open source Claude Cowork alternative", + title: "OpenWork — Open source Claude Cowork alternative for teams", description: "Bring your own model and provider, wire in your tools and context, and ship reusable agent setups across your org — with guardrails built in.", + alternates: { + canonical: "/" + }, + robots: { + index: true, + follow: true + }, openGraph: { + type: "website", + siteName: "OpenWork", + locale: "en_US", images: ["/og-image-clean.png"] }, twitter: { card: "summary_large_image", images: ["/og-image-clean.png"] - }, - icons: { - icon: "/openwork-mark.svg" } }; @@ -46,6 +64,7 @@ export default function RootLayout({ return ( +