diff --git a/apps/sim/app/(landing)/changelog/page.tsx b/apps/sim/app/(landing)/changelog/page.tsx
index 4f49f6064c3..46180cfc7c0 100644
--- a/apps/sim/app/(landing)/changelog/page.tsx
+++ b/apps/sim/app/(landing)/changelog/page.tsx
@@ -1,60 +1,17 @@
-import type { Metadata } from 'next'
-import { SITE_URL } from '@/lib/core/utils/urls'
+import { buildLandingMetadata } from '@/lib/landing/seo'
import Changelog from '@/app/(landing)/changelog/changelog'
export const revalidate = 3600
-const PAGE_URL = `${SITE_URL}/changelog`
const TITLE = 'Changelog | Sim, the AI Workspace'
const DESCRIPTION =
'Every new feature, improvement, and fix in Sim, the open-source AI workspace, with release notes straight from GitHub.'
-export const metadata: Metadata = {
- metadataBase: new URL(SITE_URL),
- title: { absolute: TITLE },
+export const metadata = buildLandingMetadata({
+ title: TITLE,
description: DESCRIPTION,
- authors: [{ name: 'Sim' }],
- creator: 'Sim',
- publisher: 'Sim',
- openGraph: {
- title: TITLE,
- description: DESCRIPTION,
- type: 'website',
- url: PAGE_URL,
- siteName: 'Sim',
- locale: 'en_US',
- images: [
- {
- url: '/logo/426-240/reverse/small.png',
- width: 2130,
- height: 1200,
- alt: 'Changelog | Sim, the AI Workspace',
- type: 'image/png',
- },
- ],
- },
- twitter: {
- card: 'summary_large_image',
- site: '@simdotai',
- creator: '@simdotai',
- title: TITLE,
- description: DESCRIPTION,
- images: {
- url: '/logo/426-240/reverse/small.png',
- alt: 'Changelog | Sim, the AI Workspace',
- },
- },
- alternates: {
- canonical: PAGE_URL,
- languages: { 'en-US': PAGE_URL, 'x-default': PAGE_URL },
- },
- robots: {
- index: true,
- follow: true,
- googleBot: { index: true, follow: true, 'max-image-preview': 'large', 'max-snippet': -1 },
- },
- category: 'technology',
-}
+ path: '/changelog',
+})
export default function Page() {
return
diff --git a/apps/sim/app/(landing)/demo/page.tsx b/apps/sim/app/(landing)/demo/page.tsx
index b91d228dfd5..5c197227422 100644
--- a/apps/sim/app/(landing)/demo/page.tsx
+++ b/apps/sim/app/(landing)/demo/page.tsx
@@ -1,60 +1,17 @@
-import type { Metadata } from 'next'
-import { SITE_URL } from '@/lib/core/utils/urls'
+import { buildLandingMetadata } from '@/lib/landing/seo'
import Demo from '@/app/(landing)/demo/demo'
export const revalidate = 3600
-const PAGE_URL = `${SITE_URL}/demo`
const TITLE = 'Book a Demo | Sim, the AI Workspace'
const DESCRIPTION =
'Book a demo of Sim, the AI agent workspace where teams build, deploy, and manage AI agents and workflows that connect 1,000+ integrations and every major LLM.'
-export const metadata: Metadata = {
- metadataBase: new URL(SITE_URL),
- title: { absolute: TITLE },
+export const metadata = buildLandingMetadata({
+ title: TITLE,
description: DESCRIPTION,
- authors: [{ name: 'Sim' }],
- creator: 'Sim',
- publisher: 'Sim',
- openGraph: {
- title: TITLE,
- description: DESCRIPTION,
- type: 'website',
- url: PAGE_URL,
- siteName: 'Sim',
- locale: 'en_US',
- images: [
- {
- url: '/logo/426-240/reverse/small.png',
- width: 2130,
- height: 1200,
- alt: 'Book a Demo | Sim, the AI Workspace',
- type: 'image/png',
- },
- ],
- },
- twitter: {
- card: 'summary_large_image',
- site: '@simdotai',
- creator: '@simdotai',
- title: TITLE,
- description: DESCRIPTION,
- images: {
- url: '/logo/426-240/reverse/small.png',
- alt: 'Book a Demo | Sim, the AI Workspace',
- },
- },
- alternates: {
- canonical: PAGE_URL,
- languages: { 'en-US': PAGE_URL, 'x-default': PAGE_URL },
- },
- robots: {
- index: true,
- follow: true,
- googleBot: { index: true, follow: true, 'max-image-preview': 'large', 'max-snippet': -1 },
- },
- category: 'technology',
-}
+ path: '/demo',
+})
export default function Page() {
return
diff --git a/apps/sim/app/(landing)/enterprise/page.tsx b/apps/sim/app/(landing)/enterprise/page.tsx
index a8ff30e2e76..8fa995cc5e0 100644
--- a/apps/sim/app/(landing)/enterprise/page.tsx
+++ b/apps/sim/app/(landing)/enterprise/page.tsx
@@ -1,59 +1,20 @@
-import type { Metadata } from 'next'
-import { SITE_URL } from '@/lib/core/utils/urls'
+import { buildLandingMetadata } from '@/lib/landing/seo'
import EnterprisePage from '@/app/(landing)/enterprise/enterprise'
export const revalidate = 3600
-const PAGE_URL = `${SITE_URL}/enterprise`
const TITLE = 'Enterprise AI Agent Platform | Sim AI'
const DESCRIPTION =
'Build, deploy, and govern enterprise AI agents in one workspace with security, approvals, observability, and collaboration.'
-export const metadata: Metadata = {
- metadataBase: new URL(SITE_URL),
- title: { absolute: TITLE },
+export const metadata = buildLandingMetadata({
+ title: TITLE,
description: DESCRIPTION,
+ path: '/enterprise',
keywords:
'enterprise ai agents, enterprise ai agent, enterprise ai agent platform, enterprise workflow agents',
- authors: [{ name: 'Sim' }],
- creator: 'Sim',
- publisher: 'Sim',
- openGraph: {
- title: TITLE,
- description: DESCRIPTION,
- type: 'website',
- url: PAGE_URL,
- siteName: 'Sim',
- locale: 'en_US',
- images: [
- {
- url: '/logo/426-240/reverse/small.png',
- width: 2130,
- height: 1200,
- alt: TITLE,
- type: 'image/png',
- },
- ],
- },
- twitter: {
- card: 'summary_large_image',
- site: '@simdotai',
- creator: '@simdotai',
- title: TITLE,
- description: DESCRIPTION,
- images: { url: '/logo/426-240/reverse/small.png', alt: 'Sim' },
- },
- alternates: {
- canonical: PAGE_URL,
- languages: { 'en-US': PAGE_URL, 'x-default': PAGE_URL },
- },
- robots: {
- index: true,
- follow: true,
- googleBot: { index: true, follow: true, 'max-image-preview': 'large', 'max-snippet': -1 },
- },
- category: 'technology',
-}
+ twitterImageAlt: 'Sim',
+})
export default function Page() {
return
diff --git a/apps/sim/app/(landing)/partners/page.tsx b/apps/sim/app/(landing)/partners/page.tsx
index e41c3a88817..05c25ed87f8 100644
--- a/apps/sim/app/(landing)/partners/page.tsx
+++ b/apps/sim/app/(landing)/partners/page.tsx
@@ -1,54 +1,20 @@
import { ChipLink } from '@sim/emcn'
-import type { Metadata } from 'next'
import { SITE_URL } from '@/lib/core/utils/urls'
+import { buildLandingMetadata } from '@/lib/landing/seo'
const PAGE_URL = `${SITE_URL}/partners`
const TITLE = 'Partner Program | Sim'
const DESCRIPTION =
"Join the Sim partner program. Build, deploy, and sell AI agent solutions powered by Sim's AI workspace, and earn your certification through Sim Academy."
-export const metadata: Metadata = {
- metadataBase: new URL(SITE_URL),
- title: { absolute: TITLE },
+export const metadata = buildLandingMetadata({
+ title: TITLE,
description: DESCRIPTION,
+ path: '/partners',
keywords:
'Sim partner program, AI agent partners, AI workspace partners, Sim Academy certification, AI agent reseller, co-marketing',
- openGraph: {
- title: TITLE,
- description: DESCRIPTION,
- type: 'website',
- url: PAGE_URL,
- siteName: 'Sim',
- locale: 'en_US',
- images: [
- {
- url: '/logo/426-240/reverse/small.png',
- width: 2130,
- height: 1200,
- alt: TITLE,
- type: 'image/png',
- },
- ],
- },
- twitter: {
- card: 'summary_large_image',
- site: '@simdotai',
- creator: '@simdotai',
- title: TITLE,
- description: DESCRIPTION,
- images: { url: '/logo/426-240/reverse/small.png', alt: 'Sim' },
- },
- alternates: {
- canonical: PAGE_URL,
- languages: { 'en-US': PAGE_URL, 'x-default': PAGE_URL },
- },
- robots: {
- index: true,
- follow: true,
- googleBot: { index: true, follow: true, 'max-image-preview': 'large', 'max-snippet': -1 },
- },
- category: 'technology',
-}
+ twitterImageAlt: 'Sim',
+})
const partnersJsonLd = {
'@context': 'https://schema.org',
diff --git a/apps/sim/app/(landing)/pricing/page.tsx b/apps/sim/app/(landing)/pricing/page.tsx
index 144c7cae205..97ada5ec6b2 100644
--- a/apps/sim/app/(landing)/pricing/page.tsx
+++ b/apps/sim/app/(landing)/pricing/page.tsx
@@ -1,64 +1,21 @@
-import type { Metadata } from 'next'
import type { SearchParams } from 'nuqs/server'
-import { SITE_URL } from '@/lib/core/utils/urls'
+import { buildLandingMetadata } from '@/lib/landing/seo'
import Pricing from '@/app/(landing)/pricing/pricing'
import { pricingSearchParamsCache } from '@/app/(landing)/pricing/search-params'
export const revalidate = 3600
-const PAGE_URL = `${SITE_URL}/pricing`
const TITLE = 'Pricing | Sim, the AI Workspace'
const DESCRIPTION =
'Pricing for Sim, the open-source AI workspace for building, deploying, and managing AI agents. Compare the Free, Pro, Max, and Enterprise plans. Start free.'
-export const metadata: Metadata = {
- metadataBase: new URL(SITE_URL),
- title: { absolute: TITLE },
+export const metadata = buildLandingMetadata({
+ title: TITLE,
description: DESCRIPTION,
+ path: '/pricing',
keywords:
'Sim pricing, AI workspace pricing, AI agent platform pricing, build AI agents, Pro plan, Max plan, Enterprise plan, open-source AI agents, LLM pricing',
- authors: [{ name: 'Sim' }],
- creator: 'Sim',
- publisher: 'Sim',
- openGraph: {
- title: TITLE,
- description: DESCRIPTION,
- type: 'website',
- url: PAGE_URL,
- siteName: 'Sim',
- locale: 'en_US',
- images: [
- {
- url: '/logo/426-240/reverse/small.png',
- width: 2130,
- height: 1200,
- alt: 'Pricing | Sim, the AI Workspace',
- type: 'image/png',
- },
- ],
- },
- twitter: {
- card: 'summary_large_image',
- site: '@simdotai',
- creator: '@simdotai',
- title: TITLE,
- description: DESCRIPTION,
- images: {
- url: '/logo/426-240/reverse/small.png',
- alt: 'Pricing | Sim, the AI Workspace',
- },
- },
- alternates: {
- canonical: PAGE_URL,
- languages: { 'en-US': PAGE_URL, 'x-default': PAGE_URL },
- },
- robots: {
- index: true,
- follow: true,
- googleBot: { index: true, follow: true, 'max-image-preview': 'large', 'max-snippet': -1 },
- },
- category: 'technology',
-}
+})
export default async function Page({ searchParams }: { searchParams: Promise }) {
await pricingSearchParamsCache.parse(searchParams)
diff --git a/apps/sim/app/(landing)/privacy/page.tsx b/apps/sim/app/(landing)/privacy/page.tsx
index c99a7a8c64a..81c2708154f 100644
--- a/apps/sim/app/(landing)/privacy/page.tsx
+++ b/apps/sim/app/(landing)/privacy/page.tsx
@@ -1,60 +1,17 @@
-import type { Metadata } from 'next'
-import { SITE_URL } from '@/lib/core/utils/urls'
+import { buildLandingMetadata } from '@/lib/landing/seo'
import Privacy from '@/app/(landing)/privacy/privacy'
export const revalidate = 3600
-const PAGE_URL = `${SITE_URL}/privacy`
const TITLE = 'Privacy Policy | Sim, the AI Workspace'
const DESCRIPTION =
'How Sim, the open-source AI workspace, collects, uses, and protects your data, including data obtained from Google APIs, and the controls you have over it.'
-export const metadata: Metadata = {
- metadataBase: new URL(SITE_URL),
- title: { absolute: TITLE },
+export const metadata = buildLandingMetadata({
+ title: TITLE,
description: DESCRIPTION,
- authors: [{ name: 'Sim' }],
- creator: 'Sim',
- publisher: 'Sim',
- openGraph: {
- title: TITLE,
- description: DESCRIPTION,
- type: 'website',
- url: PAGE_URL,
- siteName: 'Sim',
- locale: 'en_US',
- images: [
- {
- url: '/logo/426-240/reverse/small.png',
- width: 2130,
- height: 1200,
- alt: 'Privacy Policy | Sim, the AI Workspace',
- type: 'image/png',
- },
- ],
- },
- twitter: {
- card: 'summary_large_image',
- site: '@simdotai',
- creator: '@simdotai',
- title: TITLE,
- description: DESCRIPTION,
- images: {
- url: '/logo/426-240/reverse/small.png',
- alt: 'Privacy Policy | Sim, the AI Workspace',
- },
- },
- alternates: {
- canonical: PAGE_URL,
- languages: { 'en-US': PAGE_URL, 'x-default': PAGE_URL },
- },
- robots: {
- index: true,
- follow: true,
- googleBot: { index: true, follow: true, 'max-image-preview': 'large', 'max-snippet': -1 },
- },
- category: 'technology',
-}
+ path: '/privacy',
+})
export default function Page() {
return
diff --git a/apps/sim/app/(landing)/solutions/compliance/page.tsx b/apps/sim/app/(landing)/solutions/compliance/page.tsx
index 9c8467f83f4..f3c7b914933 100644
--- a/apps/sim/app/(landing)/solutions/compliance/page.tsx
+++ b/apps/sim/app/(landing)/solutions/compliance/page.tsx
@@ -1,59 +1,20 @@
-import type { Metadata } from 'next'
-import { SITE_URL } from '@/lib/core/utils/urls'
+import { buildLandingMetadata } from '@/lib/landing/seo'
import ComplianceSolution from '@/app/(landing)/solutions/compliance/compliance'
export const revalidate = 3600
-const PAGE_URL = `${SITE_URL}/solutions/compliance`
const TITLE = 'AI Agents for Continuous Compliance & Audit | Sim'
const DESCRIPTION =
'Compliance teams use Sim, the open-source AI workspace, to build and deploy AI agents that automate evidence collection, control monitoring, and reporting.'
-export const metadata: Metadata = {
- metadataBase: new URL(SITE_URL),
- title: { absolute: TITLE },
+export const metadata = buildLandingMetadata({
+ title: TITLE,
description: DESCRIPTION,
+ path: '/solutions/compliance',
keywords:
'AI workspace, AI agents for compliance, compliance automation, evidence collection, control monitoring, audit readiness, open-source AI agent platform',
- authors: [{ name: 'Sim' }],
- creator: 'Sim',
- publisher: 'Sim',
- openGraph: {
- title: TITLE,
- description: DESCRIPTION,
- type: 'website',
- url: PAGE_URL,
- siteName: 'Sim',
- locale: 'en_US',
- images: [
- {
- url: '/logo/426-240/reverse/small.png',
- width: 2130,
- height: 1200,
- alt: 'AI Agents for Continuous Compliance & Audit | Sim',
- type: 'image/png',
- },
- ],
- },
- twitter: {
- card: 'summary_large_image',
- site: '@simdotai',
- creator: '@simdotai',
- title: TITLE,
- description: DESCRIPTION,
- images: { url: '/logo/426-240/reverse/small.png', alt: 'Sim' },
- },
- alternates: {
- canonical: PAGE_URL,
- languages: { 'en-US': PAGE_URL, 'x-default': PAGE_URL },
- },
- robots: {
- index: true,
- follow: true,
- googleBot: { index: true, follow: true, 'max-image-preview': 'large', 'max-snippet': -1 },
- },
- category: 'technology',
-}
+ twitterImageAlt: 'Sim',
+})
export default function Page() {
return
diff --git a/apps/sim/app/(landing)/solutions/engineering/page.tsx b/apps/sim/app/(landing)/solutions/engineering/page.tsx
index 1eba1af08e0..7b52ba1bf5f 100644
--- a/apps/sim/app/(landing)/solutions/engineering/page.tsx
+++ b/apps/sim/app/(landing)/solutions/engineering/page.tsx
@@ -1,59 +1,20 @@
-import type { Metadata } from 'next'
-import { SITE_URL } from '@/lib/core/utils/urls'
+import { buildLandingMetadata } from '@/lib/landing/seo'
import EngineeringSolution from '@/app/(landing)/solutions/engineering/engineering'
export const revalidate = 3600
-const PAGE_URL = `${SITE_URL}/solutions/engineering`
const TITLE = 'AI Agents for Code Review & On-Call | Sim'
const DESCRIPTION =
'Engineering teams use Sim, the open-source AI workspace, to build and deploy AI agents that automate code review, on-call triage, and documentation.'
-export const metadata: Metadata = {
- metadataBase: new URL(SITE_URL),
- title: { absolute: TITLE },
+export const metadata = buildLandingMetadata({
+ title: TITLE,
description: DESCRIPTION,
+ path: '/solutions/engineering',
keywords:
'AI workspace, AI agents for engineering, automated code review, on-call automation, CI/CD agents, developer automation, open-source AI agent platform',
- authors: [{ name: 'Sim' }],
- creator: 'Sim',
- publisher: 'Sim',
- openGraph: {
- title: TITLE,
- description: DESCRIPTION,
- type: 'website',
- url: PAGE_URL,
- siteName: 'Sim',
- locale: 'en_US',
- images: [
- {
- url: '/logo/426-240/reverse/small.png',
- width: 2130,
- height: 1200,
- alt: 'AI Agents for Code Review & On-Call | Sim',
- type: 'image/png',
- },
- ],
- },
- twitter: {
- card: 'summary_large_image',
- site: '@simdotai',
- creator: '@simdotai',
- title: TITLE,
- description: DESCRIPTION,
- images: { url: '/logo/426-240/reverse/small.png', alt: 'Sim' },
- },
- alternates: {
- canonical: PAGE_URL,
- languages: { 'en-US': PAGE_URL, 'x-default': PAGE_URL },
- },
- robots: {
- index: true,
- follow: true,
- googleBot: { index: true, follow: true, 'max-image-preview': 'large', 'max-snippet': -1 },
- },
- category: 'technology',
-}
+ twitterImageAlt: 'Sim',
+})
export default function Page() {
return
diff --git a/apps/sim/app/(landing)/solutions/finance/page.tsx b/apps/sim/app/(landing)/solutions/finance/page.tsx
index 5a1754a0339..38a1e7e2196 100644
--- a/apps/sim/app/(landing)/solutions/finance/page.tsx
+++ b/apps/sim/app/(landing)/solutions/finance/page.tsx
@@ -1,59 +1,20 @@
-import type { Metadata } from 'next'
-import { SITE_URL } from '@/lib/core/utils/urls'
+import { buildLandingMetadata } from '@/lib/landing/seo'
import FinanceSolution from '@/app/(landing)/solutions/finance/finance'
export const revalidate = 3600
-const PAGE_URL = `${SITE_URL}/solutions/finance`
const TITLE = 'AI Agents for Invoice Processing & Reconciliation | Sim'
const DESCRIPTION =
'Finance teams use Sim, the open-source AI workspace, to build and deploy AI agents that automate reconciliation, invoice processing, and reporting.'
-export const metadata: Metadata = {
- metadataBase: new URL(SITE_URL),
- title: { absolute: TITLE },
+export const metadata = buildLandingMetadata({
+ title: TITLE,
description: DESCRIPTION,
+ path: '/solutions/finance',
keywords:
'AI workspace, AI agents for finance, finance automation, invoice processing, account reconciliation, financial reporting, open-source AI agent platform',
- authors: [{ name: 'Sim' }],
- creator: 'Sim',
- publisher: 'Sim',
- openGraph: {
- title: TITLE,
- description: DESCRIPTION,
- type: 'website',
- url: PAGE_URL,
- siteName: 'Sim',
- locale: 'en_US',
- images: [
- {
- url: '/logo/426-240/reverse/small.png',
- width: 2130,
- height: 1200,
- alt: 'AI Agents for Invoice Processing & Reconciliation | Sim',
- type: 'image/png',
- },
- ],
- },
- twitter: {
- card: 'summary_large_image',
- site: '@simdotai',
- creator: '@simdotai',
- title: TITLE,
- description: DESCRIPTION,
- images: { url: '/logo/426-240/reverse/small.png', alt: 'Sim' },
- },
- alternates: {
- canonical: PAGE_URL,
- languages: { 'en-US': PAGE_URL, 'x-default': PAGE_URL },
- },
- robots: {
- index: true,
- follow: true,
- googleBot: { index: true, follow: true, 'max-image-preview': 'large', 'max-snippet': -1 },
- },
- category: 'technology',
-}
+ twitterImageAlt: 'Sim',
+})
export default function Page() {
return
diff --git a/apps/sim/app/(landing)/solutions/hr/page.tsx b/apps/sim/app/(landing)/solutions/hr/page.tsx
index b593f7be9f5..ca278dd0825 100644
--- a/apps/sim/app/(landing)/solutions/hr/page.tsx
+++ b/apps/sim/app/(landing)/solutions/hr/page.tsx
@@ -1,59 +1,20 @@
-import type { Metadata } from 'next'
-import { SITE_URL } from '@/lib/core/utils/urls'
+import { buildLandingMetadata } from '@/lib/landing/seo'
import HrSolution from '@/app/(landing)/solutions/hr/hr'
export const revalidate = 3600
-const PAGE_URL = `${SITE_URL}/solutions/hr`
const TITLE = 'AI Agents for Onboarding & People Operations | Sim'
const DESCRIPTION =
'HR teams use Sim, the open-source AI workspace, to build and deploy AI agents that automate onboarding, employee questions, and approvals.'
-export const metadata: Metadata = {
- metadataBase: new URL(SITE_URL),
- title: { absolute: TITLE },
+export const metadata = buildLandingMetadata({
+ title: TITLE,
description: DESCRIPTION,
+ path: '/solutions/hr',
keywords:
'AI workspace, AI agents for HR, HR automation, employee onboarding, people operations, HRIS automation, open-source AI agent platform',
- authors: [{ name: 'Sim' }],
- creator: 'Sim',
- publisher: 'Sim',
- openGraph: {
- title: TITLE,
- description: DESCRIPTION,
- type: 'website',
- url: PAGE_URL,
- siteName: 'Sim',
- locale: 'en_US',
- images: [
- {
- url: '/logo/426-240/reverse/small.png',
- width: 2130,
- height: 1200,
- alt: 'AI Agents for Onboarding & People Operations | Sim',
- type: 'image/png',
- },
- ],
- },
- twitter: {
- card: 'summary_large_image',
- site: '@simdotai',
- creator: '@simdotai',
- title: TITLE,
- description: DESCRIPTION,
- images: { url: '/logo/426-240/reverse/small.png', alt: 'Sim' },
- },
- alternates: {
- canonical: PAGE_URL,
- languages: { 'en-US': PAGE_URL, 'x-default': PAGE_URL },
- },
- robots: {
- index: true,
- follow: true,
- googleBot: { index: true, follow: true, 'max-image-preview': 'large', 'max-snippet': -1 },
- },
- category: 'technology',
-}
+ twitterImageAlt: 'Sim',
+})
export default function Page() {
return
diff --git a/apps/sim/app/(landing)/solutions/it/page.tsx b/apps/sim/app/(landing)/solutions/it/page.tsx
index 8a17bb383e3..f3d01a5a274 100644
--- a/apps/sim/app/(landing)/solutions/it/page.tsx
+++ b/apps/sim/app/(landing)/solutions/it/page.tsx
@@ -1,59 +1,20 @@
-import type { Metadata } from 'next'
-import { SITE_URL } from '@/lib/core/utils/urls'
+import { buildLandingMetadata } from '@/lib/landing/seo'
import ItSolution from '@/app/(landing)/solutions/it/it'
export const revalidate = 3600
-const PAGE_URL = `${SITE_URL}/solutions/it`
const TITLE = 'AI Agents for Ticket Triage & Access | Sim'
const DESCRIPTION =
'IT teams use Sim, the open-source AI workspace, to build and deploy AI agents that automate ticket triage, access provisioning, and monitoring.'
-export const metadata: Metadata = {
- metadataBase: new URL(SITE_URL),
- title: { absolute: TITLE },
+export const metadata = buildLandingMetadata({
+ title: TITLE,
description: DESCRIPTION,
+ path: '/solutions/it',
keywords:
'AI workspace, IT automation, AI agents for IT, IT service desk automation, access provisioning, infrastructure monitoring, open-source AI agent platform',
- authors: [{ name: 'Sim' }],
- creator: 'Sim',
- publisher: 'Sim',
- openGraph: {
- title: TITLE,
- description: DESCRIPTION,
- type: 'website',
- url: PAGE_URL,
- siteName: 'Sim',
- locale: 'en_US',
- images: [
- {
- url: '/logo/426-240/reverse/small.png',
- width: 2130,
- height: 1200,
- alt: 'AI Agents for Ticket Triage & Access | Sim',
- type: 'image/png',
- },
- ],
- },
- twitter: {
- card: 'summary_large_image',
- site: '@simdotai',
- creator: '@simdotai',
- title: TITLE,
- description: DESCRIPTION,
- images: { url: '/logo/426-240/reverse/small.png', alt: 'Sim' },
- },
- alternates: {
- canonical: PAGE_URL,
- languages: { 'en-US': PAGE_URL, 'x-default': PAGE_URL },
- },
- robots: {
- index: true,
- follow: true,
- googleBot: { index: true, follow: true, 'max-image-preview': 'large', 'max-snippet': -1 },
- },
- category: 'technology',
-}
+ twitterImageAlt: 'Sim',
+})
export default function Page() {
return
diff --git a/apps/sim/app/(landing)/terms/page.tsx b/apps/sim/app/(landing)/terms/page.tsx
index 84949e8df53..1cad66ef3c0 100644
--- a/apps/sim/app/(landing)/terms/page.tsx
+++ b/apps/sim/app/(landing)/terms/page.tsx
@@ -1,60 +1,17 @@
-import type { Metadata } from 'next'
-import { SITE_URL } from '@/lib/core/utils/urls'
+import { buildLandingMetadata } from '@/lib/landing/seo'
import Terms from '@/app/(landing)/terms/terms'
export const revalidate = 3600
-const PAGE_URL = `${SITE_URL}/terms`
const TITLE = 'Terms of Service | Sim, the AI Workspace'
const DESCRIPTION =
'The terms and conditions for using Sim, the open-source AI workspace: subscription plans, data ownership, acceptable use, and your rights.'
-export const metadata: Metadata = {
- metadataBase: new URL(SITE_URL),
- title: { absolute: TITLE },
+export const metadata = buildLandingMetadata({
+ title: TITLE,
description: DESCRIPTION,
- authors: [{ name: 'Sim' }],
- creator: 'Sim',
- publisher: 'Sim',
- openGraph: {
- title: TITLE,
- description: DESCRIPTION,
- type: 'website',
- url: PAGE_URL,
- siteName: 'Sim',
- locale: 'en_US',
- images: [
- {
- url: '/logo/426-240/reverse/small.png',
- width: 2130,
- height: 1200,
- alt: 'Terms of Service | Sim, the AI Workspace',
- type: 'image/png',
- },
- ],
- },
- twitter: {
- card: 'summary_large_image',
- site: '@simdotai',
- creator: '@simdotai',
- title: TITLE,
- description: DESCRIPTION,
- images: {
- url: '/logo/426-240/reverse/small.png',
- alt: 'Terms of Service | Sim, the AI Workspace',
- },
- },
- alternates: {
- canonical: PAGE_URL,
- languages: { 'en-US': PAGE_URL, 'x-default': PAGE_URL },
- },
- robots: {
- index: true,
- follow: true,
- googleBot: { index: true, follow: true, 'max-image-preview': 'large', 'max-snippet': -1 },
- },
- category: 'technology',
-}
+ path: '/terms',
+})
export default function Page() {
return
diff --git a/apps/sim/app/(landing)/workflows/page.tsx b/apps/sim/app/(landing)/workflows/page.tsx
index 242f44ecf4b..532feccdc5b 100644
--- a/apps/sim/app/(landing)/workflows/page.tsx
+++ b/apps/sim/app/(landing)/workflows/page.tsx
@@ -1,62 +1,19 @@
-import type { Metadata } from 'next'
-import { SITE_URL } from '@/lib/core/utils/urls'
+import { buildLandingMetadata } from '@/lib/landing/seo'
import Workflows from '@/app/(landing)/workflows/workflows'
export const revalidate = 3600
-const PAGE_URL = `${SITE_URL}/workflows`
const TITLE = 'Workflows | The Visual Builder in Sim, the AI Workspace'
const DESCRIPTION =
'Workflows is the visual builder in Sim, the open-source AI workspace. Connect blocks, every major LLM, and 1,000+ integrations into agent logic.'
-export const metadata: Metadata = {
- metadataBase: new URL(SITE_URL),
- title: { absolute: TITLE },
+export const metadata = buildLandingMetadata({
+ title: TITLE,
description: DESCRIPTION,
+ path: '/workflows',
keywords:
'AI workspace, visual workflow builder, build AI agents, AI agent workflow builder, LLM orchestration, AI integrations, open-source AI agent platform, agentic workflows',
- authors: [{ name: 'Sim' }],
- creator: 'Sim',
- publisher: 'Sim',
- openGraph: {
- title: TITLE,
- description: DESCRIPTION,
- type: 'website',
- url: PAGE_URL,
- siteName: 'Sim',
- locale: 'en_US',
- images: [
- {
- url: '/logo/426-240/reverse/small.png',
- width: 2130,
- height: 1200,
- alt: 'Workflows | The Visual Builder in Sim, the AI Workspace',
- type: 'image/png',
- },
- ],
- },
- twitter: {
- card: 'summary_large_image',
- site: '@simdotai',
- creator: '@simdotai',
- title: TITLE,
- description: DESCRIPTION,
- images: {
- url: '/logo/426-240/reverse/small.png',
- alt: 'Workflows | The Visual Builder in Sim, the AI Workspace',
- },
- },
- alternates: {
- canonical: PAGE_URL,
- languages: { 'en-US': PAGE_URL, 'x-default': PAGE_URL },
- },
- robots: {
- index: true,
- follow: true,
- googleBot: { index: true, follow: true, 'max-image-preview': 'large', 'max-snippet': -1 },
- },
- category: 'technology',
-}
+})
export default function Page() {
return
diff --git a/apps/sim/app/workspace/[workspaceId]/upgrade/components/comparison-table/comparison-data.ts b/apps/sim/app/workspace/[workspaceId]/upgrade/components/comparison-table/comparison-data.ts
index 9b058852a94..88ddfde1922 100644
--- a/apps/sim/app/workspace/[workspaceId]/upgrade/components/comparison-table/comparison-data.ts
+++ b/apps/sim/app/workspace/[workspaceId]/upgrade/components/comparison-table/comparison-data.ts
@@ -1,3 +1,30 @@
+import {
+ CREDIT_TIERS,
+ CREDITS_PER_DOLLAR,
+ DAILY_REFRESH_RATE,
+ DEFAULT_FREE_CREDITS,
+} from '@/lib/billing/constants'
+
+/**
+ * Looks up a credit tier by name, so a column binds to the right tier even if
+ * {@link CREDIT_TIERS} is reordered or a tier is inserted.
+ */
+function tierByName(name: (typeof CREDIT_TIERS)[number]['name']) {
+ const tier = CREDIT_TIERS.find((t) => t.name === name)
+ if (!tier) throw new Error(`comparison-data: no credit tier named "${name}"`)
+ return tier
+}
+
+const PRO_TIER = tierByName('Pro')
+const MAX_TIER = tierByName('Max')
+
+/** Formats a credit count with thousands separators (e.g. 25000 → "25,000"). */
+const formatCredits = (credits: number): string => credits.toLocaleString('en-US')
+
+/** Daily refresh credits for a plan: 1% of plan dollars/day, in credits. */
+const dailyRefreshCredits = (dollars: number): number =>
+ Math.round(dollars * DAILY_REFRESH_RATE * CREDITS_PER_DOLLAR)
+
/** A brand icon rendered in a cell instead of a check/em-dash/text. */
export interface CellIcon {
/** Icon identifier resolved to a component by the table renderer. */
@@ -58,11 +85,21 @@ export const COMPARISON_SECTIONS: ComparisonSection[] = [
rows: [
{
label: 'Monthly credits',
- values: ['1,000', '6,000', '25,000', 'Custom'],
+ values: [
+ formatCredits(DEFAULT_FREE_CREDITS * CREDITS_PER_DOLLAR),
+ formatCredits(PRO_TIER.credits),
+ formatCredits(MAX_TIER.credits),
+ 'Custom',
+ ],
},
{
label: 'Daily refresh',
- values: [false, '+50', '+200', 'Custom'],
+ values: [
+ false,
+ `+${formatCredits(dailyRefreshCredits(PRO_TIER.dollars))}`,
+ `+${formatCredits(dailyRefreshCredits(MAX_TIER.dollars))}`,
+ 'Custom',
+ ],
},
],
},
diff --git a/apps/sim/lib/billing/constants.ts b/apps/sim/lib/billing/constants.ts
index ce20115db8b..d4e60cd74ee 100644
--- a/apps/sim/lib/billing/constants.ts
+++ b/apps/sim/lib/billing/constants.ts
@@ -50,6 +50,12 @@ export const CREDIT_TIERS = [
export type CreditTier = (typeof CREDIT_TIERS)[number]
+/**
+ * Credits granted per dollar of plan spend. A credit is $0.005, so a dollar
+ * buys 200 — the conversion behind both free-tier and daily-refresh credits.
+ */
+export const CREDITS_PER_DOLLAR = 200
+
/**
* Daily refresh rate: 1% of plan cost per day.
* E.g. $25 plan => $0.25/day => 50 credits/day included usage.
diff --git a/apps/sim/lib/landing/seo.ts b/apps/sim/lib/landing/seo.ts
new file mode 100644
index 00000000000..d0f04f50caf
--- /dev/null
+++ b/apps/sim/lib/landing/seo.ts
@@ -0,0 +1,89 @@
+import type { Metadata } from 'next'
+import { SITE_URL } from '@/lib/core/utils/urls'
+
+/** Shared OpenGraph/Twitter card image for landing pages. */
+const OG_IMAGE_URL = '/logo/426-240/reverse/small.png'
+const OG_IMAGE_WIDTH = 2130
+const OG_IMAGE_HEIGHT = 1200
+
+interface LandingMetadataInput {
+ /** Absolute ``, rendered as-is (no site template applied). */
+ title: string
+ description: string
+ /** Path under the site root, e.g. `/pricing`. Use `''` for the home page. */
+ path: string
+ /** Optional comma-separated keywords; omitted from the output when absent. */
+ keywords?: string
+ /** OpenGraph image alt text. Defaults to {@link title}. */
+ imageAlt?: string
+ /** Twitter card image alt text. Defaults to {@link imageAlt}. */
+ twitterImageAlt?: string
+}
+
+/**
+ * Builds the canonical metadata for a static landing page — the single source of
+ * truth for the OpenGraph/Twitter/robots/canonical chrome shared across the
+ * landing family, so per-page files declare only what actually varies (title,
+ * description, keywords, path, and any non-default image alt).
+ *
+ * Note: dynamic and image-bearing routes that resolve their card from a sibling
+ * `opengraph-image` (integrations, models) and the blog family (`buildPostMetadata`
+ * in `lib/blog/seo`) intentionally do not use this helper.
+ */
+export function buildLandingMetadata({
+ title,
+ description,
+ path,
+ keywords,
+ imageAlt,
+ twitterImageAlt,
+}: LandingMetadataInput): Metadata {
+ const url = `${SITE_URL}${path}`
+ const ogAlt = imageAlt ?? title
+ const twitterAlt = twitterImageAlt ?? ogAlt
+
+ return {
+ metadataBase: new URL(SITE_URL),
+ title: { absolute: title },
+ description,
+ ...(keywords ? { keywords } : {}),
+ authors: [{ name: 'Sim' }],
+ creator: 'Sim',
+ publisher: 'Sim',
+ openGraph: {
+ title,
+ description,
+ type: 'website',
+ url,
+ siteName: 'Sim',
+ locale: 'en_US',
+ images: [
+ {
+ url: OG_IMAGE_URL,
+ width: OG_IMAGE_WIDTH,
+ height: OG_IMAGE_HEIGHT,
+ alt: ogAlt,
+ type: 'image/png',
+ },
+ ],
+ },
+ twitter: {
+ card: 'summary_large_image',
+ site: '@simdotai',
+ creator: '@simdotai',
+ title,
+ description,
+ images: { url: OG_IMAGE_URL, alt: twitterAlt },
+ },
+ alternates: {
+ canonical: url,
+ languages: { 'en-US': url, 'x-default': url },
+ },
+ robots: {
+ index: true,
+ follow: true,
+ googleBot: { index: true, follow: true, 'max-image-preview': 'large', 'max-snippet': -1 },
+ },
+ category: 'technology',
+ }
+}