From fbe9b776604d2536a676657b13caf6029ae35810 Mon Sep 17 00:00:00 2001 From: Mekjah Date: Sun, 31 May 2026 20:40:06 +0100 Subject: [PATCH] feat: add /integrations marketing page (#integrations-404) --- apps/www/public/integrations/brex.svg | 1 + apps/www/public/integrations/chargebee.svg | 1 + apps/www/public/integrations/datadog.svg | 1 + apps/www/public/integrations/front.svg | 1 + apps/www/public/integrations/intercom.svg | 1 + apps/www/public/integrations/linear.svg | 1 + apps/www/public/integrations/maxio.svg | 1 + apps/www/public/integrations/mercury.svg | 1 + .../integrations/mixpanel-amplitude.svg | 1 + .../public/integrations/modern-treasury.svg | 1 + apps/www/public/integrations/netsuite.svg | 1 + apps/www/public/integrations/pagerduty.svg | 1 + apps/www/public/integrations/posthog.svg | 1 + .../public/integrations/quickbooks-online.svg | 1 + apps/www/public/integrations/recurly.svg | 1 + apps/www/public/integrations/sage-intacct.svg | 1 + apps/www/public/integrations/segment.svg | 1 + apps/www/public/integrations/sentry.svg | 1 + .../public/integrations/stripe-billing.svg | 1 + apps/www/public/integrations/xero.svg | 1 + apps/www/public/integrations/zendesk.svg | 1 + .../src/app/(marketing)/integrations/page.tsx | 167 ++++++++++++++++ apps/www/src/app/sitemap.ts | 6 + apps/www/src/lib/integrations.ts | 181 ++++++++++++++++++ 24 files changed, 375 insertions(+) create mode 100644 apps/www/public/integrations/brex.svg create mode 100644 apps/www/public/integrations/chargebee.svg create mode 100644 apps/www/public/integrations/datadog.svg create mode 100644 apps/www/public/integrations/front.svg create mode 100644 apps/www/public/integrations/intercom.svg create mode 100644 apps/www/public/integrations/linear.svg create mode 100644 apps/www/public/integrations/maxio.svg create mode 100644 apps/www/public/integrations/mercury.svg create mode 100644 apps/www/public/integrations/mixpanel-amplitude.svg create mode 100644 apps/www/public/integrations/modern-treasury.svg create mode 100644 apps/www/public/integrations/netsuite.svg create mode 100644 apps/www/public/integrations/pagerduty.svg create mode 100644 apps/www/public/integrations/posthog.svg create mode 100644 apps/www/public/integrations/quickbooks-online.svg create mode 100644 apps/www/public/integrations/recurly.svg create mode 100644 apps/www/public/integrations/sage-intacct.svg create mode 100644 apps/www/public/integrations/segment.svg create mode 100644 apps/www/public/integrations/sentry.svg create mode 100644 apps/www/public/integrations/stripe-billing.svg create mode 100644 apps/www/public/integrations/xero.svg create mode 100644 apps/www/public/integrations/zendesk.svg create mode 100644 apps/www/src/app/(marketing)/integrations/page.tsx create mode 100644 apps/www/src/lib/integrations.ts diff --git a/apps/www/public/integrations/brex.svg b/apps/www/public/integrations/brex.svg new file mode 100644 index 0000000..06383db --- /dev/null +++ b/apps/www/public/integrations/brex.svg @@ -0,0 +1 @@ +BR \ No newline at end of file diff --git a/apps/www/public/integrations/chargebee.svg b/apps/www/public/integrations/chargebee.svg new file mode 100644 index 0000000..2c11099 --- /dev/null +++ b/apps/www/public/integrations/chargebee.svg @@ -0,0 +1 @@ +CH \ No newline at end of file diff --git a/apps/www/public/integrations/datadog.svg b/apps/www/public/integrations/datadog.svg new file mode 100644 index 0000000..3b52cbb --- /dev/null +++ b/apps/www/public/integrations/datadog.svg @@ -0,0 +1 @@ +DA \ No newline at end of file diff --git a/apps/www/public/integrations/front.svg b/apps/www/public/integrations/front.svg new file mode 100644 index 0000000..76c82e3 --- /dev/null +++ b/apps/www/public/integrations/front.svg @@ -0,0 +1 @@ +FR \ No newline at end of file diff --git a/apps/www/public/integrations/intercom.svg b/apps/www/public/integrations/intercom.svg new file mode 100644 index 0000000..87d6f2c --- /dev/null +++ b/apps/www/public/integrations/intercom.svg @@ -0,0 +1 @@ +IN \ No newline at end of file diff --git a/apps/www/public/integrations/linear.svg b/apps/www/public/integrations/linear.svg new file mode 100644 index 0000000..52bf5a9 --- /dev/null +++ b/apps/www/public/integrations/linear.svg @@ -0,0 +1 @@ +LI \ No newline at end of file diff --git a/apps/www/public/integrations/maxio.svg b/apps/www/public/integrations/maxio.svg new file mode 100644 index 0000000..c18d711 --- /dev/null +++ b/apps/www/public/integrations/maxio.svg @@ -0,0 +1 @@ +MA \ No newline at end of file diff --git a/apps/www/public/integrations/mercury.svg b/apps/www/public/integrations/mercury.svg new file mode 100644 index 0000000..a461dac --- /dev/null +++ b/apps/www/public/integrations/mercury.svg @@ -0,0 +1 @@ +ME \ No newline at end of file diff --git a/apps/www/public/integrations/mixpanel-amplitude.svg b/apps/www/public/integrations/mixpanel-amplitude.svg new file mode 100644 index 0000000..055de23 --- /dev/null +++ b/apps/www/public/integrations/mixpanel-amplitude.svg @@ -0,0 +1 @@ +MI \ No newline at end of file diff --git a/apps/www/public/integrations/modern-treasury.svg b/apps/www/public/integrations/modern-treasury.svg new file mode 100644 index 0000000..12443f1 --- /dev/null +++ b/apps/www/public/integrations/modern-treasury.svg @@ -0,0 +1 @@ +MO \ No newline at end of file diff --git a/apps/www/public/integrations/netsuite.svg b/apps/www/public/integrations/netsuite.svg new file mode 100644 index 0000000..7810c8d --- /dev/null +++ b/apps/www/public/integrations/netsuite.svg @@ -0,0 +1 @@ +NE \ No newline at end of file diff --git a/apps/www/public/integrations/pagerduty.svg b/apps/www/public/integrations/pagerduty.svg new file mode 100644 index 0000000..b98f6ff --- /dev/null +++ b/apps/www/public/integrations/pagerduty.svg @@ -0,0 +1 @@ +PA \ No newline at end of file diff --git a/apps/www/public/integrations/posthog.svg b/apps/www/public/integrations/posthog.svg new file mode 100644 index 0000000..5f7d2ce --- /dev/null +++ b/apps/www/public/integrations/posthog.svg @@ -0,0 +1 @@ +PO \ No newline at end of file diff --git a/apps/www/public/integrations/quickbooks-online.svg b/apps/www/public/integrations/quickbooks-online.svg new file mode 100644 index 0000000..6b08910 --- /dev/null +++ b/apps/www/public/integrations/quickbooks-online.svg @@ -0,0 +1 @@ +QU \ No newline at end of file diff --git a/apps/www/public/integrations/recurly.svg b/apps/www/public/integrations/recurly.svg new file mode 100644 index 0000000..2c02f73 --- /dev/null +++ b/apps/www/public/integrations/recurly.svg @@ -0,0 +1 @@ +RE \ No newline at end of file diff --git a/apps/www/public/integrations/sage-intacct.svg b/apps/www/public/integrations/sage-intacct.svg new file mode 100644 index 0000000..b395d3d --- /dev/null +++ b/apps/www/public/integrations/sage-intacct.svg @@ -0,0 +1 @@ +SA \ No newline at end of file diff --git a/apps/www/public/integrations/segment.svg b/apps/www/public/integrations/segment.svg new file mode 100644 index 0000000..507f9c0 --- /dev/null +++ b/apps/www/public/integrations/segment.svg @@ -0,0 +1 @@ +SE \ No newline at end of file diff --git a/apps/www/public/integrations/sentry.svg b/apps/www/public/integrations/sentry.svg new file mode 100644 index 0000000..507f9c0 --- /dev/null +++ b/apps/www/public/integrations/sentry.svg @@ -0,0 +1 @@ +SE \ No newline at end of file diff --git a/apps/www/public/integrations/stripe-billing.svg b/apps/www/public/integrations/stripe-billing.svg new file mode 100644 index 0000000..dc26fe2 --- /dev/null +++ b/apps/www/public/integrations/stripe-billing.svg @@ -0,0 +1 @@ +ST \ No newline at end of file diff --git a/apps/www/public/integrations/xero.svg b/apps/www/public/integrations/xero.svg new file mode 100644 index 0000000..98e7f5a --- /dev/null +++ b/apps/www/public/integrations/xero.svg @@ -0,0 +1 @@ +XE \ No newline at end of file diff --git a/apps/www/public/integrations/zendesk.svg b/apps/www/public/integrations/zendesk.svg new file mode 100644 index 0000000..a1ff22f --- /dev/null +++ b/apps/www/public/integrations/zendesk.svg @@ -0,0 +1 @@ +ZE \ No newline at end of file diff --git a/apps/www/src/app/(marketing)/integrations/page.tsx b/apps/www/src/app/(marketing)/integrations/page.tsx new file mode 100644 index 0000000..60a413b --- /dev/null +++ b/apps/www/src/app/(marketing)/integrations/page.tsx @@ -0,0 +1,167 @@ +import fs from "fs"; +import path from "path"; +import { fileURLToPath } from "url"; +import type { Metadata } from "next"; +import Image from "next/image"; +import Link from "next/link"; +import { ArrowUpRight } from "lucide-react"; +import { PageShell } from "@/components/site/PageShell"; +import { PageEnter } from "@/components/site/PageEnter"; +import { PageMast } from "@/components/v2/PageMast"; +import { INTEGRATIONS, type Integration } from "@/lib/integrations"; + +const publicIntegrationsDir = path.join( + path.dirname(fileURLToPath(import.meta.url)), + "../../../../public/integrations", +); + +const availableLogos = new Set( + fs.existsSync(publicIntegrationsDir) + ? fs.readdirSync(publicIntegrationsDir).filter((fileName) => fileName.endsWith(".svg")) + : [], +); + +const statusStyles: Record = { + live: "bg-emerald-100 text-emerald-900", + "coming-soon": "bg-amber-100 text-amber-900", + "on-request": "bg-slate-100 text-slate-900", +}; + +const statusLabel: Record = { + live: "Live", + "coming-soon": "Coming soon", + "on-request": "On request", +}; + +function getInitials(name: string) { + return name + .replace(/[^A-Za-z0-9]/g, "") + .slice(0, 2) + .toUpperCase(); +} + +function hasLogo(slug: string) { + return availableLogos.has(`${slug}.svg`); +} + +const categoryGroups = INTEGRATIONS.reduce>((groups, integration) => { + (groups[integration.category] ??= []).push(integration); + return groups; +}, {}); + +const categories = Object.entries(categoryGroups); + +export const metadata: Metadata = { + title: "Integrations | Useroutr", + description: + "Connect Useroutr to your accounting, treasury, billing, support, and dev tools.", +}; + +export default async function IntegrationsPage() { + return ( + + + + +
+
+
+ {categories.map(([category, items]) => ( +
+

+ {category} +

+
+ {items.map((integration) => ( +
+
+
+ {hasLogo(integration.logoSlug) ? ( + {`${integration.name} + ) : ( +
+ {getInitials(integration.name)} +
+ )} +
+
+
+

+ {integration.name} +

+ + {statusLabel[integration.status]} + +
+

+ {integration.description || "More details coming soon."} +

+
+
+
+ ))} +
+
+ ))} + +
+
+

Don't see yours?

+

+ Request an integration from the Useroutr team, and we’ll follow up with next steps. +

+
+ + Request an integration + + +
+
+ +
+

Build your own

+

+ Use Useroutr's API docs to connect your internal systems or build a custom integration. +

+
+ + Read the API docs + + +
+
+
+
+
+
+
+
+ ); +} diff --git a/apps/www/src/app/sitemap.ts b/apps/www/src/app/sitemap.ts index 6847ae2..f7639f8 100644 --- a/apps/www/src/app/sitemap.ts +++ b/apps/www/src/app/sitemap.ts @@ -26,6 +26,12 @@ export default function sitemap(): MetadataRoute.Sitemap { changeFrequency: "monthly", priority: 0.9, }, + { + url: `${baseUrl}/integrations`, + lastModified: now, + changeFrequency: "monthly", + priority: 0.8, + }, ...useCases.map((slug) => ({ url: `${baseUrl}/use-cases/${slug}`, lastModified: now, diff --git a/apps/www/src/lib/integrations.ts b/apps/www/src/lib/integrations.ts new file mode 100644 index 0000000..24b7714 --- /dev/null +++ b/apps/www/src/lib/integrations.ts @@ -0,0 +1,181 @@ +export type IntegrationStatus = "live" | "coming-soon" | "on-request"; + +export interface Integration { + id: string; + name: string; + category: string; + description: string; + status: IntegrationStatus; + logoSlug: string; +} + +export const INTEGRATIONS: Integration[] = [ + { + id: "quickbooks-online", + name: "QuickBooks Online", + category: "Accounting & ERP", + description: "Sync payments → revenue, fees → expense.", + status: "live", + logoSlug: "quickbooks-online", + }, + { + id: "xero", + name: "Xero", + category: "Accounting & ERP", + description: "Same.", + status: "live", + logoSlug: "xero", + }, + { + id: "netsuite", + name: "NetSuite", + category: "Accounting & ERP", + description: "Full GL sync, multi-entity, multi-currency.", + status: "coming-soon", + logoSlug: "netsuite", + }, + { + id: "sage-intacct", + name: "Sage Intacct", + category: "Accounting & ERP", + description: "Coming soon.", + status: "coming-soon", + logoSlug: "sage-intacct", + }, + { + id: "modern-treasury", + name: "Modern Treasury", + category: "Treasury & Finance", + description: "Payouts orchestration + bank rail abstraction.", + status: "live", + logoSlug: "modern-treasury", + }, + { + id: "mercury", + name: "Mercury", + category: "Treasury & Finance", + description: "Settlement balance sync.", + status: "coming-soon", + logoSlug: "mercury", + }, + { + id: "brex", + name: "Brex", + category: "Treasury & Finance", + description: "Card spend sync.", + status: "coming-soon", + logoSlug: "brex", + }, + { + id: "stripe-billing", + name: "Stripe Billing", + category: "Billing & Subscriptions", + description: "Useroutr handles settlement, Stripe handles subscriptions.", + status: "live", + logoSlug: "stripe-billing", + }, + { + id: "chargebee", + name: "Chargebee", + category: "Billing & Subscriptions", + description: "Webhook bridge for renewal events.", + status: "live", + logoSlug: "chargebee", + }, + { + id: "recurly", + name: "Recurly", + category: "Billing & Subscriptions", + description: "Request access.", + status: "on-request", + logoSlug: "recurly", + }, + { + id: "maxio", + name: "Maxio", + category: "Billing & Subscriptions", + description: "Request access.", + status: "on-request", + logoSlug: "maxio", + }, + { + id: "segment", + name: "Segment", + category: "Customer Data & Analytics", + description: "Stream payment events to anywhere.", + status: "live", + logoSlug: "segment", + }, + { + id: "mixpanel-amplitude", + name: "Mixpanel / Amplitude", + category: "Customer Data & Analytics", + description: "Pre-built event mappings.", + status: "live", + logoSlug: "mixpanel-amplitude", + }, + { + id: "posthog", + name: "PostHog", + category: "Customer Data & Analytics", + description: "Open-source bridge.", + status: "live", + logoSlug: "posthog", + }, + { + id: "intercom", + name: "Intercom", + category: "Support & Success", + description: "Pull payment + dispute context into customer conversations.", + status: "live", + logoSlug: "intercom", + }, + { + id: "zendesk", + name: "Zendesk", + category: "Support & Success", + description: "Same.", + status: "live", + logoSlug: "zendesk", + }, + { + id: "front", + name: "Front", + category: "Support & Success", + description: "Same.", + status: "live", + logoSlug: "front", + }, + { + id: "linear", + name: "Linear", + category: "Dev Tools", + description: "Open issues from failed webhooks.", + status: "live", + logoSlug: "linear", + }, + { + id: "pagerduty", + name: "PagerDuty", + category: "Dev Tools", + description: "Pager on /readyz alerts.", + status: "live", + logoSlug: "pagerduty", + }, + { + id: "sentry", + name: "Sentry", + category: "Dev Tools", + description: "Auto-attach Useroutr request IDs.", + status: "live", + logoSlug: "sentry", + }, + { + id: "datadog", + name: "Datadog", + category: "Dev Tools", + description: "Metrics + trace correlation.", + status: "live", + logoSlug: "datadog", + }, +];