docs(nx-dev): add solutions sections and components (#31239)

It adds a new "Solutions" section to the Nx Dev website with three targeted landing pages for different audiences: engineering teams, management teams platform teams, and leadership.

It creates three new page files (engineering.tsx, management.tsx, leadership.tsx, platform.tsx) that showcase Nx's benefits through various UI components like heroes, testimonials, feature sections, and FAQs. Each page highlights specific value propositions - engineering focuses on developer efficiency and standards, platform emphasizes reliable CI/CD scaling, and leadership addresses ROI and risk reduction.

The navigation is updated with a new "Solutions" dropdown menu in both desktop and mobile views, with corresponding menu items defined. The solutions pages include consistent sections like customer logos, calls-to-action, testimonials, and feature breakdowns that highlight Nx's capabilities for different stakeholders.
This commit is contained in:
Benjamin Cabanes 2025-05-16 13:55:47 -04:00 committed by GitHub
parent a5ccd13f92
commit ccfcc4097f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 3175 additions and 8 deletions

View File

@ -0,0 +1,82 @@
import { useRouter } from 'next/router';
import { NextSeo } from 'next-seo';
import { ButtonLinkProps, DefaultLayout } from '@nx/nx-dev/ui-common';
import {
AllSpeedNoStress,
CustomerLogos,
DeveloperExperienceThatWorksForYou,
HetznerCloudTestimonial,
SolutionsBottomCallToAction,
SolutionsEngineeringHero,
SolutionsEngineeringTestimonials,
SolutionsFaq,
SolutionsTopCallToAction,
} from '@nx/nx-dev/ui-enterprise';
import { type ReactElement } from 'react';
export function EnterpriseSolutionsEngineering(): ReactElement {
const router = useRouter();
const headerCTAConfig: ButtonLinkProps[] = [
{
href: '/contact',
variant: 'secondary',
size: 'small',
title: 'Contact us',
children: 'Contact us',
},
];
return (
<>
<NextSeo
title="Build confidently, ship faster without waiting on your tools."
description="Build confidently and ship faster with Nx: unleash remote caching, flaky test retries, parallel e2e, dynamic agents, log streaming, powerful tooling, AI LLM integration, and plugins."
canonical="https://nx.dev/solutionss/engineering"
openGraph={{
url: 'https://nx.dev' + router.asPath,
title: '',
description:
'Build confidently and ship faster with Nx: unleash remote caching, flaky test retries, parallel e2e, dynamic agents, log streaming, powerful tooling, AI LLM integration, and plugins.',
images: [
{
url: 'https://nx.dev/socials/nx-media.png',
width: 800,
height: 421,
alt: 'Nx: Smart Monorepos · Fast CI',
type: 'image/jpeg',
},
],
siteName: 'Nx',
type: 'website',
}}
/>
<DefaultLayout headerCTAConfig={headerCTAConfig}>
<SolutionsEngineeringHero />
<CustomerLogos />
<SolutionsTopCallToAction />
<div className="mt-32 lg:mt-56">
<AllSpeedNoStress />
</div>
<div className="mt-32 lg:mt-56">
<HetznerCloudTestimonial />
</div>
<div className="mt-32 lg:mt-56">
<DeveloperExperienceThatWorksForYou />
</div>
<div className="mt-32 lg:mt-56">
<SolutionsEngineeringTestimonials />
</div>
<div className="mt-32 lg:mt-56">
<SolutionsFaq />
</div>
<div className="mt-32 lg:mt-56">
<SolutionsBottomCallToAction />
</div>
</DefaultLayout>
</>
);
}
export default EnterpriseSolutionsEngineering;

View File

@ -0,0 +1,86 @@
import { useRouter } from 'next/router';
import { NextSeo } from 'next-seo';
import { ButtonLinkProps, DefaultLayout } from '@nx/nx-dev/ui-common';
import {
BuildAModernEngineeringOrganization,
CustomerLogos,
HetznerCloudTestimonial,
MaximizeRoi,
ScaleSafely,
SolutionsBottomCallToAction,
SolutionsFaq,
SolutionsLeadershipHero,
SolutionsLeadershipTestimonials,
SolutionsTopCallToAction,
} from '@nx/nx-dev/ui-enterprise';
import { type ReactElement } from 'react';
export function EnterpriseSolutionsLeadership(): ReactElement {
const router = useRouter();
const headerCTAConfig: ButtonLinkProps[] = [
{
href: '/contact',
variant: 'secondary',
size: 'small',
title: 'Contact us',
children: 'Contact us',
},
];
return (
<>
<NextSeo
title="Fast Delivery. Low Risk. High ROI."
description="Supercharge engineering ROI with faster delivery, lower CI costs, and fewer risks. Scale safely, futureproof your stack, and leverage AIassisted workflows."
canonical="https://nx.dev/solutions/leadership"
openGraph={{
url: 'https://nx.dev' + router.asPath,
title: 'Fast Delivery. Low Risk. High ROI.',
description:
'Supercharge engineering ROI with faster delivery, lower CI costs, and fewer risks. Scale safely, futureproof your stack, and leverage AIassisted workflows.',
images: [
{
url: 'https://nx.dev/socials/nx-media.png',
width: 800,
height: 421,
alt: 'Nx: Smart Monorepos · Fast CI',
type: 'image/jpeg',
},
],
siteName: 'Nx',
type: 'website',
}}
/>
<DefaultLayout headerCTAConfig={headerCTAConfig}>
<SolutionsLeadershipHero />
<CustomerLogos />
<SolutionsTopCallToAction />
<div className="mt-32 lg:mt-56">
<MaximizeRoi />
</div>
<div className="mt-32 lg:mt-56">
<ScaleSafely />
</div>
<div className="mt-32 lg:mt-56">
<HetznerCloudTestimonial />
</div>
<div className="mt-32 lg:mt-56">
<BuildAModernEngineeringOrganization />
</div>
<div className="mt-32 lg:mt-56">
<SolutionsLeadershipTestimonials />
</div>
<div className="mt-32 lg:mt-56">
<SolutionsFaq />
</div>
<div className="mt-32 lg:mt-56">
<SolutionsBottomCallToAction />
</div>
</DefaultLayout>
</>
);
}
export default EnterpriseSolutionsLeadership;

View File

@ -0,0 +1,85 @@
import { useRouter } from 'next/router';
import { NextSeo } from 'next-seo';
import { ButtonLinkProps, DefaultLayout } from '@nx/nx-dev/ui-common';
import {
CustomerLogos,
CutDownEngineeringWaste,
HetznerCloudTestimonial,
KeepTeamsAligned,
ScaleWithEase,
SolutionsManagementHero,
SolutionsBottomCallToAction,
SolutionsManagementTestimonials,
SolutionsFaq,
SolutionsTopCallToAction,
} from '@nx/nx-dev/ui-enterprise';
import { type ReactElement } from 'react';
export function EnterpriseSolutionsManagement(): ReactElement {
const router = useRouter();
const headerCTAConfig: ButtonLinkProps[] = [
{
href: '/contact',
variant: 'secondary',
size: 'small',
title: 'Contact us',
children: 'Contact us',
},
];
return (
<>
<NextSeo
title="Standardize, scale, and ship with less waste"
description="Align, scale, and cut engineering waste with Nx. Enable developer mobility, enforce standards, and optimize CI/CD with powerful AI insights."
canonical="https://nx.dev/solutionss/management"
openGraph={{
url: 'https://nx.dev' + router.asPath,
title: 'Standardize, scale, and ship with less waste',
description:
'Align, scale, and cut engineering waste with Nx. Enable developer mobility, enforce standards, and optimize CI/CD with powerful AI insights.',
images: [
{
url: 'https://nx.dev/socials/nx-media.png',
width: 800,
height: 421,
alt: 'Nx: Smart Monorepos · Fast CI',
type: 'image/jpeg',
},
],
siteName: 'Nx',
type: 'website',
}}
/>
<DefaultLayout headerCTAConfig={headerCTAConfig}>
<SolutionsManagementHero />
<CustomerLogos />
<SolutionsTopCallToAction />
<div className="mt-32 lg:mt-56">
<KeepTeamsAligned />
</div>
<div className="mt-32 lg:mt-56">
<ScaleWithEase />
</div>
<div className="mt-32 lg:mt-56">
<HetznerCloudTestimonial />
</div>
<div className="mt-32 lg:mt-56">
<CutDownEngineeringWaste />
</div>
<div className="mt-32 lg:mt-56">
<SolutionsManagementTestimonials />
</div>
<div className="mt-32 lg:mt-56">
<SolutionsFaq />
</div>
<div className="mt-32 lg:mt-56">
<SolutionsBottomCallToAction />
</div>
</DefaultLayout>
</>
);
}
export default EnterpriseSolutionsManagement;

View File

@ -0,0 +1,85 @@
import { useRouter } from 'next/router';
import { NextSeo } from 'next-seo';
import { ButtonLinkProps, DefaultLayout } from '@nx/nx-dev/ui-common';
import {
CostEfficientCompute,
CustomerLogos,
EasyToAdoptEasyToMaintain,
HetznerCloudTestimonial,
ReliableByDesign,
SolutionsBottomCallToAction,
SolutionsFaq,
SolutionsPlatformHero,
SolutionsPlatformTestimonials,
SolutionsTopCallToAction,
} from '@nx/nx-dev/ui-enterprise';
import { type ReactElement } from 'react';
export function EnterpriseSolutionsPlatform(): ReactElement {
const router = useRouter();
const headerCTAConfig: ButtonLinkProps[] = [
{
href: '/contact',
variant: 'secondary',
size: 'small',
title: 'Contact us',
children: 'Contact us',
},
];
return (
<>
<NextSeo
title="CI that works out of the box and stays reliable at scale"
description="Nx delivers reliable, out-of-the-box CI that scales. Cut costs and boost speed with smart caching, compute distribution, and enhanced security for your pipelines."
canonical="https://nx.dev/solutionss/platform"
openGraph={{
url: 'https://nx.dev' + router.asPath,
title: 'CI that works out of the box and stays reliable at scale',
description:
'Nx delivers reliable, out-of-the-box CI that scales. Cut costs and boost speed with smart caching, compute distribution, and enhanced security for your pipelines.',
images: [
{
url: 'https://nx.dev/socials/nx-media.png',
width: 800,
height: 421,
alt: 'Nx: Smart Monorepos · Fast CI',
type: 'image/jpeg',
},
],
siteName: 'Nx',
type: 'website',
}}
/>
<DefaultLayout headerCTAConfig={headerCTAConfig}>
<SolutionsPlatformHero />
<CustomerLogos />
<SolutionsTopCallToAction />
<div className="mt-32 lg:mt-56">
<EasyToAdoptEasyToMaintain />
</div>
<div className="mt-32 lg:mt-56">
<ReliableByDesign />
</div>
<div className="mt-32 lg:mt-56">
<HetznerCloudTestimonial />
</div>
<div className="mt-32 lg:mt-56">
<CostEfficientCompute />
</div>
<div className="mt-32 lg:mt-56">
<SolutionsPlatformTestimonials />
</div>
<div className="mt-32 lg:mt-56">
<SolutionsFaq />
</div>
<div className="mt-32 lg:mt-56">
<SolutionsBottomCallToAction />
</div>
</DefaultLayout>
</>
);
}
export default EnterpriseSolutionsPlatform;

View File

@ -25,7 +25,11 @@ import {
useState,
} from 'react';
import { ButtonLink, ButtonLinkProps } from '../button';
import { enterpriseItems, resourceMenuItems } from './menu-items';
import {
enterpriseItems,
resourceMenuItems,
solutionsItems,
} from './menu-items';
import { MobileMenuItem } from './mobile-menu-item';
import { SectionsMenu } from './sections-menu';
import { AlgoliaSearch } from '@nx/nx-dev/feature-search';
@ -120,6 +124,50 @@ export function Header({ ctaButtons }: HeaderProps): ReactElement {
>
Blog
</Link>
{/*SOLUTIONS*/}
<Popover className="relative">
{({ open }) => (
<>
<PopoverButton
className={cx(
open ? 'text-blue-500 dark:text-sky-500' : '',
'group inline-flex items-center px-3 py-2 font-medium leading-tight outline-0 dark:text-slate-200'
)}
>
<span className="transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500">
Solutions
</span>
<ChevronDownIcon
className={cx(
open
? 'rotate-180 transform text-blue-500 dark:text-sky-500'
: '',
'ml-2 h-3 w-3 transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
)}
aria-hidden="true"
/>
</PopoverButton>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel className="absolute left-60 z-30 mt-3 w-max max-w-2xl -translate-x-1/2 transform lg:left-20">
<SectionsMenu
sections={{
'Speed, Reliability and AI': solutionsItems,
}}
/>
</Popover.Panel>
</Transition>
</>
)}
</Popover>
{/*RESOURCES*/}
<Popover className="relative">
{({ open }) => (
@ -186,6 +234,7 @@ export function Header({ ctaButtons }: HeaderProps): ReactElement {
Pricing
</Link>
<div className="hidden h-6 w-px bg-slate-200 md:block dark:bg-slate-700" />
{/*ENTERPRISE*/}
<Popover className="relative">
{({ open }) => (
<>
@ -379,7 +428,46 @@ export function Header({ ctaButtons }: HeaderProps): ReactElement {
>
Blog
</Link>
{/*Resources*/}
{/*SOLUTIONS*/}
<Disclosure as="div">
{({ open }) => (
<>
<DisclosureButton
className={cx(
open
? 'text-blue-500 dark:text-sky-500'
: 'tex-slate-800 dark:text-slate-200',
'flex w-full items-center justify-between py-4 text-left text-base font-medium focus:outline-none'
)}
>
<span>Solutions</span>
<ChevronDownIcon
aria-hidden="true"
className={cx(
open
? 'rotate-180 transform text-blue-500 dark:text-sky-500'
: 'tex-slate-800 dark:text-slate-200',
'h-3 w-3 transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
)}
/>
</DisclosureButton>
<Disclosure.Panel
as="ul"
className="space-y-1 pb-2"
>
{Object.values(solutionsItems)
.flat()
.map((item) => (
<MobileMenuItem
key={item.name}
item={item}
/>
))}
</Disclosure.Panel>
</>
)}
</Disclosure>
{/*RESOURCES*/}
<Disclosure as="div">
{({ open }) => (
<>

View File

@ -19,6 +19,9 @@ import {
LifebuoyIcon,
BookOpenIcon,
ShieldCheckIcon,
ServerStackIcon,
ArrowTrendingUpIcon,
CommandLineIcon,
} from '@heroicons/react/24/outline';
import { FC, SVGProps } from 'react';
import { DiscordIcon } from '../discord-icon';
@ -233,6 +236,44 @@ export const eventItems: MenuItem[] = [
},
];
export const solutionsItems: MenuItem[] = [
{
name: 'Developers',
description:
'Accelerate your CI with Nx: smart cache sharing, flaky-test autoretries, parallel runs & dynamic agents.',
href: '/solutions/engineering',
icon: CommandLineIcon,
isNew: false,
isHighlight: false,
},
{
name: 'Engineering Managers',
description:
'Boost efficiency with powerful monorepos and intelligent CI. Build, test, and deploy faster, freeing teams to innovate.',
href: '/solutions/management',
icon: BoltIcon,
isNew: false,
isHighlight: false,
},
{
name: 'Platform & DevOps Teams',
description:
'Get dependable, out-of-the-box CI that scales effortlessly. Cut costs and boost speed with smart caching, distribution, and enhanced security.',
icon: ServerStackIcon,
href: '/solutions/platform',
isNew: false,
isHighlight: false,
},
{
name: 'CTOs & VPs of Engineering',
description:
'Supercharge engineering ROI with faster delivery, lower CI costs, and fewer risks. Scale safely and future-proof your stack.',
icon: ArrowTrendingUpIcon,
href: '/solutions/leadership',
isNew: false,
isHighlight: false,
},
];
export const companyItems: MenuItem[] = [
{
name: 'About Us',
@ -261,9 +302,9 @@ export const companyItems: MenuItem[] = [
];
export const enterpriseItems: MenuItem[] = [
{
name: 'Solutions',
name: 'Overview',
description:
"Accelerate your organization's journey to tighter collaboration, better developer experience, and speed.",
"Accelerate your organization's journey to tighter collaboration, better developer experience, and speed…lots of speed.",
href: '/enterprise',
icon: BuildingOfficeIcon,
isNew: false,

View File

@ -1,4 +1,4 @@
import { ElementType } from 'react';
import type { ElementType, ReactElement } from 'react';
import type { MenuItem } from './menu-items';
import cx from 'classnames';
import Link from 'next/link';
@ -12,21 +12,21 @@ export function MobileMenuItem({
as?: ElementType;
className?: string;
item: MenuItem;
}): JSX.Element {
}): ReactElement {
const hasExternalLink =
item.href.startsWith('http') || item.href.startsWith('//');
const Tag = as;
return (
<Tag
className={cx(
'relative flex flex-1 items-center gap-2 rounded-lg py-3',
'items-top relative flex flex-1 gap-2 rounded-lg py-3',
item.isHighlight ? 'bg-slate-50 px-2 dark:bg-slate-800/80' : '',
className
)}
{...rest}
>
{item.icon ? (
<item.icon aria-hidden="true" className="h-4 w-4 shrink-0" />
<item.icon aria-hidden="true" className="mt-1.5 size-4 shrink-0" />
) : null}
<div className="grow">
<Link

View File

@ -19,3 +19,26 @@ export * from './lib/security/ci-access';
export * from './lib/security/build-for-enterprise';
export * from './lib/security/call-to-action';
export * from './lib/security/failing-compliance';
export * from './lib/solutions/engineering/all-speed-no-stress';
export * from './lib/solutions/engineering/developer-experience-that-works-for-you';
export * from './lib/solutions/engineering/solutions-engineering-hero';
export * from './lib/solutions/engineering/solutions-engineering-testimonials';
export * from './lib/solutions/management/solutions-management-hero';
export * from './lib/solutions/management/keep-teams-aligned';
export * from './lib/solutions/management/scale-with-ease';
export * from './lib/solutions/management/cut-down-engineering-waste';
export * from './lib/solutions/management/solutions-management-testimonials';
export * from './lib/solutions/platform/easy-to-adapt-easy-to-maintain';
export * from './lib/solutions/platform/reliable-by-design';
export * from './lib/solutions/platform/solutions-platform-hero';
export * from './lib/solutions/platform/cost-efficient-compute';
export * from './lib/solutions/platform/solutions-platform-testimonials';
export * from './lib/solutions/leadership/maximize-roi';
export * from './lib/solutions/leadership/scale-safely';
export * from './lib/solutions/leadership/build-a-modern-engineering-organization';
export * from './lib/solutions/leadership/solutions-leadership-hero';
export * from './lib/solutions/leadership/solutions-leadership-testimonials';
export * from './lib/solutions/platform/cost-efficient-compute';
export * from './lib/solutions/solutions-bottom-call-to-action';
export * from './lib/solutions/solutions-top-call-to-action';
export * from './lib/solutions/solutions-faq';

View File

@ -0,0 +1,140 @@
import {
ArchiveBoxIcon,
ArrowPathIcon,
ArrowsRightLeftIcon,
CloudArrowUpIcon,
RocketLaunchIcon,
ShieldCheckIcon,
SparklesIcon,
Squares2X2Icon,
} from '@heroicons/react/24/outline';
import { ReactElement } from 'react';
import { SectionHeading } from '@nx/nx-dev/ui-common';
import Link from 'next/link';
const features = [
{
name: 'Never build the same code twice',
description: (
<>
<p className="flex-auto">
Reduce build times and resource usage by sharing cached results across
your team and CI pipelines.
</p>
<div className="mt-4">
<Link
href="/ci/features/remote-cache"
title="Learn more about Nx Replay"
className="text-sm/6 font-semibold"
>
Learn more about Nx Replay <span aria-hidden="true"></span>
</Link>
</div>
</>
),
icon: ArchiveBoxIcon,
},
{
name: 'One less thing to debug',
description: (
<>
<p className="flex-auto">
Automatically detect and re-run flaky tasks to minimize time spent
debugging.
</p>
<div className="mt-4">
<Link
href="/ci/features/flaky-tasks"
title="Learn more about Flaky Task Retries"
className="text-sm/6 font-semibold"
>
Learn more about Flaky Task Retries{' '}
<span aria-hidden="true"></span>
</Link>
</div>
</>
),
icon: ArrowPathIcon,
},
{
name: 'Break tasks down, to speed tests up',
description: (
<>
<p className="flex-auto">
Split large e2e suites into parallel runs that finish in minutes, not
hours.
</p>
<div className="mt-4">
<Link
href="/ci/features/split-e2e-tasks"
title="Learn about Atomizer"
className="text-sm/6 font-semibold"
>
Learn about Atomizer <span aria-hidden="true"></span>
</Link>
</div>
</>
),
icon: Squares2X2Icon,
},
{
name: 'Machines, make it fast',
description: (
<>
<p className="flex-auto">
Dynamically distribute tasks across machines for faster builds and PR
feedback.
</p>
<div className="mt-4">
<Link
href="/ci/features/dynamic-agents"
title="Learn about Nx Agents"
className="text-sm/6 font-semibold"
>
Learn about Nx Agents <span aria-hidden="true"></span>
</Link>
</div>
</>
),
icon: RocketLaunchIcon,
},
];
export function AllSpeedNoStress(): ReactElement {
return (
<div
id="all-speed-no-stress"
className="mx-auto max-w-7xl scroll-mt-32 px-6 lg:px-8"
>
<div className="mx-auto max-w-2xl lg:mx-0">
<div className="h-8 w-36 border-t-2 border-blue-500 dark:border-sky-500" />
<SectionHeading as="h2" variant="title" id="all-speed-no-stress-title">
All speed no stress
</SectionHeading>
<SectionHeading as="p" variant="subtitle" className="mt-6">
Stay in flow with fewer distractions and dramatically faster CI.
</SectionHeading>
</div>
<div className="mx-auto mt-16 max-w-2xl sm:mt-20 lg:mt-24 lg:max-w-none">
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-16 lg:max-w-none lg:grid-cols-2">
{features.map((feature) => (
<div key={feature.name} className="flex flex-col">
<dt className="text-base/7 font-semibold">
<div className="mb-6 flex size-10 items-center justify-center rounded-lg bg-blue-500 dark:bg-sky-500">
<feature.icon
aria-hidden="true"
className="size-6 text-white"
/>
</div>
{feature.name}
</dt>
<dd className="mt-1 flex flex-auto flex-col text-base/7">
{feature.description}
</dd>
</div>
))}
</dl>
</div>
</div>
);
}

View File

@ -0,0 +1,135 @@
import {
CommandLineIcon,
EyeIcon,
PuzzlePieceIcon,
SparklesIcon,
} from '@heroicons/react/24/outline';
import { ReactElement } from 'react';
import { SectionHeading } from '@nx/nx-dev/ui-common';
import Link from 'next/link';
const features = [
{
name: 'Reduce time to meaningful feedback',
description: (
<p className="flex-auto">
<Link
href="/blog/nx-editor-ci-llm-integration#why-this-matters-optimizing-time-to-meaningful-feedback"
title="Nx allows you to stream test errors and logs to your editor while CI is still running"
prefetch={false}
className="underline"
>
Stream test errors and logs to your editor while CI is still running
</Link>
, helping you iterate faster and avoid unnecessary context switching.
</p>
),
icon: EyeIcon,
},
{
name: 'Powerful local tooling',
description: (
<>
<p className="flex-auto">
Work faster with deep editor integrations, an AI-enabled terminal UI,
and a fast, Rust-based task orchestrator.
</p>
<div className="mt-4">
<Link
href="/getting-started/editor-setup"
title="Learn about Nx Console"
className="text-sm/6 font-semibold"
>
Learn about Nx Console <span aria-hidden="true"></span>
</Link>
</div>
</>
),
icon: CommandLineIcon,
},
{
name: 'AI LLM integrations',
description: (
<>
<p className="flex-auto">
Enable your AI assistant to move beyond local file changes with
architectural awareness, best practices context, and deep integration
into your CI and local tooling.
</p>
<div className="mt-4">
<Link
href="/features/enhance-AI"
title="Learn about Enhancing your LLM"
className="text-sm/6 font-semibold"
>
Learn about Enhancing your LLM <span aria-hidden="true"></span>
</Link>
</div>
</>
),
icon: SparklesIcon,
},
{
name: 'Plugin support',
description: (
<>
<p className="flex-auto">
Bring your stack and extend Nx to fit your needs.
</p>
<div className="mt-4">
<Link
href="/plugin-registry"
title="View our Plugin Registry"
className="text-sm/6 font-semibold"
>
View our Plugin Registry <span aria-hidden="true"></span>
</Link>
</div>
</>
),
icon: PuzzlePieceIcon,
},
];
export function DeveloperExperienceThatWorksForYou(): ReactElement {
return (
<div
id="developer-experience-that-works-for-you"
className="mx-auto max-w-7xl scroll-mt-32 px-6 lg:px-8"
>
<div className="mx-auto max-w-2xl lg:mx-0">
<div className="h-8 w-36 border-t-2 border-pink-500 dark:border-fuchsia-500" />
<SectionHeading
as="h2"
variant="title"
id="developer-experience-that-works-for-you-title"
>
Developer Experience That Works for You
</SectionHeading>
<SectionHeading as="p" variant="subtitle" className="mt-6">
Great DX means more focus, less frustration.
</SectionHeading>
</div>
<div className="mx-auto mt-16 max-w-2xl sm:mt-20 lg:mt-24 lg:max-w-none">
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-16 lg:max-w-none lg:grid-cols-2">
{features.map((feature) => (
<div key={feature.name} className="flex flex-col">
<dt className="text-base/7 font-semibold">
<div className="mb-6 flex size-10 items-center justify-center rounded-lg bg-pink-500 dark:bg-fuchsia-500">
<feature.icon
aria-hidden="true"
className="size-6 text-white"
/>
</div>
{feature.name}
</dt>
<dd className="mt-1 flex flex-auto flex-col text-base/7">
{feature.description}
</dd>
</div>
))}
</dl>
</div>
</div>
);
}

View File

@ -0,0 +1,206 @@
import { ComponentProps, ReactElement, useState } from 'react';
import { ButtonLink, SectionHeading, VideoModal } from '@nx/nx-dev/ui-common';
import { sendCustomEvent } from '@nx/nx-dev/feature-analytics';
import {
ChevronRightIcon,
EnvelopeIcon,
PlayIcon,
} from '@heroicons/react/24/outline';
import Image from 'next/image';
import { UkgIcon } from '@nx/nx-dev/ui-icons';
import { cx } from '@nx/nx-dev/ui-primitives';
import { MovingBorder } from '@nx/nx-dev/ui-animations';
import { motion } from 'framer-motion';
function PlayButton({
className,
...props
}: ComponentProps<'div'>): ReactElement {
const parent = {
initial: {
width: 82,
transition: {
when: 'afterChildren',
},
},
hover: {
width: 296,
transition: {
duration: 0.125,
type: 'tween',
ease: 'easeOut',
},
},
};
const child = {
initial: {
opacity: 0,
x: -6,
},
hover: {
x: 0,
opacity: 1,
transition: {
duration: 0.015,
type: 'tween',
ease: 'easeOut',
},
},
};
return (
<div
className={cx(
'group relative overflow-hidden rounded-full bg-transparent p-[1px] shadow-md',
className
)}
{...props}
>
<div className="absolute inset-0">
<MovingBorder duration={5000} rx="5%" ry="5%">
<div className="size-20 bg-[radial-gradient(var(--blue-500)_40%,transparent_60%)] opacity-[0.8] dark:bg-[radial-gradient(var(--pink-500)_40%,transparent_60%)]" />
</MovingBorder>
</div>
<motion.div
initial="initial"
whileHover="hover"
variants={parent}
className="relative isolate flex size-20 cursor-pointer items-center justify-center gap-6 rounded-full border-2 border-slate-100 bg-white/10 p-6 text-white antialiased backdrop-blur-xl"
>
<PlayIcon aria-hidden="true" className="absolute left-6 top-6 size-8" />
<motion.div variants={child} className="absolute left-20 top-4 w-48">
<p className="text-base font-medium">Watch the interview</p>
<p className="text-xs">Under 3 minutes.</p>
</motion.div>
</motion.div>
</div>
);
}
export function SolutionsEngineeringHero(): ReactElement {
const [isOpen, setIsOpen] = useState(false);
return (
<section className="relative overflow-hidden">
<div className="mx-auto max-w-7xl lg:flex">
<div className="mx-auto max-w-3xl px-6 py-24 lg:mx-0 lg:shrink-0 lg:px-8">
<p>
<a
href="https://bit.ly/4jQLCqp"
title="See live event in details"
className="group/event-link inline-flex space-x-6"
>
<span className="rounded-full bg-blue-600/10 px-3 py-1 text-sm/6 font-semibold text-blue-600 ring-1 ring-inset ring-blue-600/10 dark:bg-cyan-600/10 dark:text-cyan-600 dark:ring-cyan-600/10">
Live event
</span>
<span className="inline-flex items-center space-x-2 text-sm/6 font-medium">
<span>Webinar + live Q&A on May 28th</span>
<ChevronRightIcon
aria-hidden="true"
className="size-5 transform transition-all group-hover/event-link:translate-x-1"
/>
</span>
</a>
</p>
<SectionHeading
id="get-speed-and-scale"
as="h1"
variant="display"
className="mt-8 text-pretty tracking-tight"
>
Build confidently, ship faster{' '}
<span className="rounded-lg bg-gradient-to-r from-blue-500 to-sky-500 bg-clip-text text-transparent">
without waiting on your tools
</span>
</SectionHeading>
<SectionHeading
as="p"
variant="subtitle"
className="mx-auto mt-6 max-w-3xl lg:pr-20"
>
Accelerate your CI with Nx: smart cache sharing, flaky-test
autoretries, parallel runs & dynamic agents.
</SectionHeading>
<div className="mt-8 flex items-center gap-x-3">
<ButtonLink
href="/contact/sales"
title="Talk to our team"
variant="primary"
size="default"
onClick={() =>
sendCustomEvent(
'contact-sales-click',
'solutions-engineering-hero',
'solutions-engineering'
)
}
>
Talk to our team
</ButtonLink>
<ButtonLink
href="https://go.nx.dev/nx-newsletter"
title="Talk to the team"
variant="secondary"
size="default"
onClick={() =>
sendCustomEvent(
'contact-sales-click',
'solutions-engineering-hero',
'solutions-engineering'
)
}
>
<EnvelopeIcon aria-hidden="true" className="size-4" />
<span>Subscribe to the newsletter</span>
</ButtonLink>
</div>
</div>
<div className="flex items-center justify-end">
<div>
<div className="relative">
<Image
src="/images/customers/video-story-ukg.avif"
alt="video still"
width={960}
height={540}
loading="lazy"
unoptimized
className="relative rounded-xl"
/>
<div className="absolute inset-0 grid h-full w-full items-center justify-center">
<PlayButton
onClick={() => {
setIsOpen(true);
sendCustomEvent(
'ukg-testimonial-video-click',
'ukg-testimonial-solutions',
'solutions'
);
}}
/>
</div>
</div>
<div className="mt-4 flex items-center gap-x-4 text-sm/6">
<UkgIcon
aria-hidden="true"
className="size-10 flex-none shrink-0 text-[#005151] dark:text-white"
/>
<div>
Discover how UKG reduced build times while scaling development
across teams with Nx.
</div>
</div>
</div>
<VideoModal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
videoUrl="https://youtu.be/rSC8wihnfP4"
/>
</div>
</div>
</section>
);
}

View File

@ -0,0 +1,103 @@
import type { ReactElement } from 'react';
import {
CasewareIcon,
HetznerCloudIcon,
PayfitIcon,
SiriusxmAlternateIcon,
UkgIcon,
VmwareIcon,
} from '@nx/nx-dev/ui-icons';
import { SectionHeading } from '@nx/nx-dev/ui-common';
export function SolutionsEngineeringTestimonials(): ReactElement {
return (
<div className="border border-slate-100 bg-slate-50 px-6 py-24 sm:px-6 sm:py-32 lg:px-8 dark:border-slate-900 dark:bg-slate-900/[0.8]">
<div className="mx-auto max-w-5xl text-center">
<SectionHeading as="h2" variant="title" id="testimonials">
Hear from developers like you
</SectionHeading>
<SectionHeading as="p" variant="subtitle" className="mt-6">
Don't just take our word for it. See how Nx transforms development for
teams worldwide.
</SectionHeading>
</div>
<div className="mx-auto grid max-w-7xl gap-8 lg:grid-cols-3">
<figure className="mt-16 flex flex-col justify-between rounded-lg bg-white p-4 pl-8 dark:bg-slate-950">
<blockquote className="text-base/7">
<p>
Using Nx Cloud, our CI times have reduced by 83%! Our teams are
not waiting hours for their PR to be merged anymore and we
reclaimed our productivity.
</p>
</blockquote>
<figcaption className="mt-6 flex items-center gap-x-4 text-sm/6">
<img
alt="Laurent Delamare, Senior Engineer, VMware"
src="https://avatars.githubusercontent.com/u/11790472?v=4"
className="size-8 flex-none rounded-full"
/>
<div>
<div className="font-semibold">Laurent Delamare</div>
<div className="text-slate-500">Senior Engineer, VMware</div>
</div>
<VmwareIcon
aria-hidden="true"
className="mx-auto size-14 flex-none shrink-0 text-white"
/>
</figcaption>
</figure>
<figure className="mt-16 flex flex-col justify-between rounded-lg bg-white p-4 pl-8 dark:bg-slate-950">
<blockquote className="text-base/7">
<p>
"Engineers will run a test command and expect it to run for 20
mins, when it finishes in a few seconds, they ask Did I start it
wrong? Why is it so fast?"
</p>
</blockquote>
<figcaption className="mt-6 flex items-center gap-x-4 text-sm/6">
<img
alt="Pavlo Grosse, Senior Software Engineer, Hetzner Cloud"
src="https://avatars.githubusercontent.com/u/2219064?v=4"
className="size-8 flex-none rounded-full"
/>
<div>
<div className="font-semibold">Pavlo Grosse</div>
<div className="text-slate-500">
Senior Engineer, Hetzner Cloud
</div>
</div>
<HetznerCloudIcon
aria-hidden="true"
className="mx-auto size-10 flex-none shrink-0 bg-white text-[#D50C2D]"
/>
</figcaption>
</figure>
<figure className="mt-16 flex flex-col justify-between rounded-lg bg-white p-4 pl-8 dark:bg-slate-950">
<blockquote className="text-base/7">
<p>
"Maintaining our own CI was not efficient. With Nx Cloud our
developers can focus on the things that actually matter for DevEx
and create a good experience for our customers."
</p>
</blockquote>
<figcaption className="mt-6 flex items-center gap-x-4 text-sm/6">
<img
alt="Sid Govindaraju, Engineering Manager, UKG"
src="https://media.licdn.com/dms/image/v2/C4D03AQH0wxtNq8Brhw/profile-displayphoto-shrink_200_200/profile-displayphoto-shrink_200_200/0/1639897842208?e=2147483647&v=beta&t=wPVxARsxwab6nvYv6DrsP1XnjsUksa2Nmx5kPlp2ny8"
className="size-8 flex-none rounded-full"
/>
<div>
<div className="font-semibold">Sid Govindaraju</div>
<div className="text-slate-500">Engineering Manager, UKG</div>
</div>
<UkgIcon
aria-hidden="true"
className="ml-auto size-10 shrink-0 text-[#005151] dark:text-white"
/>
</figcaption>
</figure>
</div>
</div>
);
}

View File

@ -0,0 +1,101 @@
import {
ArrowPathIcon,
LockClosedIcon,
SparklesIcon,
} from '@heroicons/react/24/outline';
import { ReactElement } from 'react';
import { SectionHeading } from '@nx/nx-dev/ui-common';
import Link from 'next/link';
const features = [
{
name: 'Enable AI-assisted development',
description: (
<>
<p className="flex-auto">
Make LLMs and internal tooling smarter by providing real-time
architecture and usage context, giving your teams a strategic edge in
how quickly and confidently they can ship.
</p>
<div className="mt-4">
<Link
href="/features/enhance-AI"
title="Learn about our Enhancing your LLM"
className="text-sm/6 font-semibold"
>
Learn about our Enhancing your LLM <span aria-hidden="true"></span>
</Link>
</div>
</>
),
icon: SparklesIcon,
},
{
name: 'Ensure security and compliance',
description: (
<>
<p className="flex-auto">
Quickly surface issues and roll out org-wide fixes with built-in
controls and governance.
</p>
</>
),
icon: LockClosedIcon,
},
{
name: 'Future-proof your stack',
description: (
<>
<p className="flex-auto">
Stay flexible with a platform that integrates with your current setup
and evolves with your needs.
</p>
</>
),
icon: ArrowPathIcon,
},
];
export function BuildAModernEngineeringOrganization(): ReactElement {
return (
<div
id="build-a-modern-engineering-org"
className="mx-auto max-w-7xl scroll-mt-32 px-6 lg:px-8"
>
<div className="mx-auto max-w-2xl lg:mx-0">
<div className="h-8 w-36 border-t-2 border-pink-500 dark:border-fuchsia-500" />
<SectionHeading
as="h2"
variant="title"
id="build-a-modern-engineering-org-title"
>
Build a Modern Engineering Org
</SectionHeading>
<SectionHeading as="p" variant="subtitle" className="mt-6">
Enable the next generation of developer workflows and team
collaboration.
</SectionHeading>
</div>
<div className="mx-auto mt-16 max-w-2xl sm:mt-20 lg:mt-24 lg:max-w-none">
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-16 lg:max-w-none lg:grid-cols-3">
{features.map((feature) => (
<div key={feature.name} className="flex flex-col">
<dt className="text-base/7 font-semibold">
<div className="mb-6 flex size-10 items-center justify-center rounded-lg bg-pink-500 dark:bg-fuchsia-500">
<feature.icon
aria-hidden="true"
className="size-6 text-white"
/>
</div>
{feature.name}
</dt>
<dd className="mt-1 flex flex-auto flex-col text-base/7">
{feature.description}
</dd>
</div>
))}
</dl>
</div>
</div>
);
}

View File

@ -0,0 +1,84 @@
import {
BanknotesIcon,
BoltIcon,
BugAntIcon,
} from '@heroicons/react/24/outline';
import { ReactElement } from 'react';
import { SectionHeading } from '@nx/nx-dev/ui-common';
const features = [
{
name: 'Reduce CI costs',
description: (
<p className="flex-auto">
Avoid over-provisioning and eliminate redundant work with smarter task
distribution and caching.
</p>
),
icon: BanknotesIcon,
},
{
name: 'Faster time to market',
description: (
<>
<p className="flex-auto">
Speed up iteration cycles, reduce delivery bottlenecks, and gain a
competitive edge by getting value to customers faster.
</p>
</>
),
icon: BoltIcon,
},
{
name: 'Minimize the cost of failure',
description: (
<>
<p className="flex-auto">
Shift problem detection earlier in the processwith real-time
feedbackto reduce the impact of bugs and regressions
</p>
</>
),
icon: BugAntIcon,
},
];
export function MaximizeRoi(): ReactElement {
return (
<div
id="maximize-roi"
className="mx-auto max-w-7xl scroll-mt-32 px-6 lg:px-8"
>
<div className="mx-auto max-w-2xl lg:mx-0">
<div className="h-8 w-36 border-t-2 border-green-500" />
<SectionHeading as="h2" variant="title" id="maximize-roi-title">
Maximize ROI
</SectionHeading>
<SectionHeading as="p" variant="subtitle" className="mt-6">
Free up engineering capacity and increase the return on every build
minute.
</SectionHeading>
</div>
<div className="mx-auto mt-16 max-w-2xl sm:mt-20 lg:mt-24 lg:max-w-none">
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-16 lg:max-w-none lg:grid-cols-3">
{features.map((feature) => (
<div key={feature.name} className="flex flex-col">
<dt className="text-base/7 font-semibold">
<div className="mb-6 flex size-10 items-center justify-center rounded-lg bg-green-500">
<feature.icon
aria-hidden="true"
className="size-6 text-white"
/>
</div>
{feature.name}
</dt>
<dd className="mt-1 flex flex-auto flex-col text-base/7">
{feature.description}
</dd>
</div>
))}
</dl>
</div>
</div>
);
}

View File

@ -0,0 +1,87 @@
import {
ClipboardDocumentListIcon,
EyeIcon,
UsersIcon,
} from '@heroicons/react/24/outline';
import { ReactElement } from 'react';
import { SectionHeading } from '@nx/nx-dev/ui-common';
const features = [
{
name: 'Standardize across the org',
description: (
<>
<p className="flex-auto">
Establish and enforce consistent development standards so everyone
builds from the same playbook.
</p>
</>
),
icon: ClipboardDocumentListIcon,
},
{
name: 'Break silos, improve collaboration',
description: (
<>
<p className="flex-auto">
Increase code reuse and cross-team velocity through shared context and
tooling.
</p>
</>
),
icon: UsersIcon,
},
{
name: 'Smarter visibility',
description: (
<>
<p className="flex-auto">
Understand how everything fits together with tools that map
relationships, dependencies, and ownershipso you can make decisions
faster and avoid delays caused by hidden complexity.
</p>
</>
),
icon: EyeIcon,
},
];
export function ScaleSafely(): ReactElement {
return (
<div
id="scale-safely"
className="mx-auto max-w-7xl scroll-mt-32 px-6 lg:px-8"
>
<div className="mx-auto max-w-2xl lg:mx-0">
<div className="h-8 w-36 border-t-2 border-blue-500 dark:border-sky-500" />
<SectionHeading as="h2" variant="title" id="scale-safely-title">
Scale Safely
</SectionHeading>
<SectionHeading as="p" variant="subtitle" className="mt-6">
Set a foundation that supports growth without introducing operational
risk.
</SectionHeading>
</div>
<div className="mx-auto mt-16 max-w-2xl sm:mt-20 lg:mt-24 lg:max-w-none">
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-16 lg:max-w-none lg:grid-cols-3">
{features.map((feature) => (
<div key={feature.name} className="flex flex-col">
<dt className="text-base/7 font-semibold">
<div className="mb-6 flex size-10 items-center justify-center rounded-lg bg-blue-500 dark:bg-sky-500">
<feature.icon
aria-hidden="true"
className="size-6 text-white"
/>
</div>
{feature.name}
</dt>
<dd className="mt-1 flex flex-auto flex-col text-base/7">
{feature.description}
</dd>
</div>
))}
</dl>
</div>
</div>
);
}

View File

@ -0,0 +1,208 @@
import { ComponentProps, ReactElement, useState } from 'react';
import { ButtonLink, SectionHeading, VideoModal } from '@nx/nx-dev/ui-common';
import { sendCustomEvent } from '@nx/nx-dev/feature-analytics';
import {
ChevronRightIcon,
EnvelopeIcon,
PlayIcon,
} from '@heroicons/react/24/outline';
import { cx } from '@nx/nx-dev/ui-primitives';
import { MovingBorder } from '@nx/nx-dev/ui-animations';
import { motion } from 'framer-motion';
import Image from 'next/image';
import { CasewareIcon, UkgIcon } from '@nx/nx-dev/ui-icons';
function PlayButton({
className,
...props
}: ComponentProps<'div'>): ReactElement {
const parent = {
initial: {
width: 82,
transition: {
when: 'afterChildren',
},
},
hover: {
width: 296,
transition: {
duration: 0.125,
type: 'tween',
ease: 'easeOut',
},
},
};
const child = {
initial: {
opacity: 0,
x: -6,
},
hover: {
x: 0,
opacity: 1,
transition: {
duration: 0.015,
type: 'tween',
ease: 'easeOut',
},
},
};
return (
<div
className={cx(
'group relative overflow-hidden rounded-full bg-transparent p-[1px] shadow-md',
className
)}
{...props}
>
<div className="absolute inset-0">
<MovingBorder duration={5000} rx="5%" ry="5%">
<div className="size-20 bg-[radial-gradient(var(--blue-500)_40%,transparent_60%)] opacity-[0.8] dark:bg-[radial-gradient(var(--pink-500)_40%,transparent_60%)]" />
</MovingBorder>
</div>
<motion.div
initial="initial"
whileHover="hover"
variants={parent}
className="relative isolate flex size-20 cursor-pointer items-center justify-center gap-6 rounded-full border-2 border-slate-100 bg-white/10 p-6 text-white antialiased backdrop-blur-xl"
>
<PlayIcon aria-hidden="true" className="absolute left-6 top-6 size-8" />
<motion.div variants={child} className="absolute left-20 top-4 w-48">
<p className="text-base font-medium">Watch the interview</p>
<p className="text-xs">Under 3 minutes.</p>
</motion.div>
</motion.div>
</div>
);
}
export function SolutionsLeadershipHero(): ReactElement {
const [isOpen, setIsOpen] = useState(false);
return (
<section className="relative overflow-hidden">
<div className="mx-auto max-w-7xl lg:flex">
<div className="mx-auto max-w-3xl px-6 py-24 lg:mx-0 lg:shrink-0 lg:px-8">
<p>
<a
href="https://bit.ly/4jQLCqp"
title="See live event in details"
className="group/event-link inline-flex space-x-6"
>
<span className="rounded-full bg-blue-600/10 px-3 py-1 text-sm/6 font-semibold text-blue-600 ring-1 ring-inset ring-blue-600/10 dark:bg-cyan-600/10 dark:text-cyan-600 dark:ring-cyan-600/10">
Live event
</span>
<span className="inline-flex items-center space-x-2 text-sm/6 font-medium">
<span>Webinar + live Q&A on May 28th</span>
<ChevronRightIcon
aria-hidden="true"
className="size-5 transform transition-all group-hover/event-link:translate-x-1"
/>
</span>
</a>
</p>
<SectionHeading
id="get-speed-and-scale"
as="h1"
variant="display"
className="mt-8 text-pretty tracking-tight"
>
Fast Delivery <br className="lg:block" /> Low Risk
<br className="lg:block" />
<span className="rounded-lg bg-gradient-to-r from-blue-500 to-sky-500 bg-clip-text text-transparent">
High ROI
</span>
</SectionHeading>
<SectionHeading
as="p"
variant="subtitle"
className="mx-auto mt-6 max-w-3xl lg:pr-20"
>
Supercharge engineering ROI with faster delivery, lower CI costs,
and fewer risks. Scale safely, futureproof your stack, and leverage
AIassisted workflows.
</SectionHeading>
<div className="mt-8 flex items-center gap-x-3">
<ButtonLink
href="/contact/sales"
title="Talk to our team"
variant="primary"
size="default"
onClick={() =>
sendCustomEvent(
'contact-sales-click',
'solutions-leadership-hero',
'solutions-leadership'
)
}
>
Talk to our team
</ButtonLink>
<ButtonLink
href="https://go.nx.dev/nx-newsletter"
title="Talk to the team"
variant="secondary"
size="default"
onClick={() =>
sendCustomEvent(
'contact-sales-click',
'solutions-leadership-hero',
'solutions-leadership'
)
}
>
<EnvelopeIcon aria-hidden="true" className="size-4" />
<span>Subscribe to the newsletter</span>
</ButtonLink>
</div>
</div>
<div className="flex items-center justify-end">
<div>
<div className="relative">
<Image
src="/images/customers/video-story-caseware.avif"
alt="video still"
width={960}
height={540}
loading="lazy"
unoptimized
className="relative rounded-xl"
/>
<div className="absolute inset-0 grid h-full w-full items-center justify-center">
<PlayButton
onClick={() => {
setIsOpen(true);
sendCustomEvent(
'caseware-testimonial-video-click',
'caseware-testimonial-solutions',
'solutions'
);
}}
/>
</div>
</div>
<div className="mt-4 flex items-center gap-x-4 text-sm/6">
<CasewareIcon
aria-hidden="true"
className="size-10 flex-none shrink-0 text-[#F56354]"
/>
<div>
Scaling 700+ projects: How Nx Enterprise became a 'no-brainer'
for Caseware.
</div>
</div>
</div>
<VideoModal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
videoUrl="https://youtu.be/lvS8HjjFwEM"
/>
</div>
</div>
</section>
);
}

View File

@ -0,0 +1,103 @@
import type { ReactElement } from 'react';
import {
CasewareIcon,
HetznerCloudIcon,
PayfitIcon,
SiriusxmAlternateIcon,
} from '@nx/nx-dev/ui-icons';
import { SectionHeading } from '@nx/nx-dev/ui-common';
export function SolutionsLeadershipTestimonials(): ReactElement {
return (
<div className="border border-slate-100 bg-slate-50 px-6 py-24 sm:px-6 sm:py-32 lg:px-8 dark:border-slate-900 dark:bg-slate-900/[0.8]">
<div className="mx-auto max-w-5xl text-center">
<SectionHeading as="h2" variant="title" id="testimonials">
Hear from developers like you
</SectionHeading>
<SectionHeading as="p" variant="subtitle" className="mt-6">
Don't just take our word for it. See how Nx transforms development for
teams worldwide.
</SectionHeading>
</div>
<div className="mx-auto grid max-w-7xl gap-8 lg:grid-cols-3">
<figure className="mt-16 flex flex-col justify-between rounded-lg bg-white p-4 pl-8 dark:bg-slate-950">
<blockquote className="text-base/7">
<p>
"The hours we spent manually load balancing in CircleCI was
painful. With Nx Cloud we offload that complexity and that keeps
velocity at scale in a large monorepo."
</p>
</blockquote>
<figcaption className="mt-6 flex items-center gap-x-4 text-sm/6">
<img
alt="Nicolas Beaussart, Staff Platform Engineer, Payfit"
src="https://avatars.githubusercontent.com/u/7281023?v=4"
className="size-8 flex-none rounded-full"
/>
<div>
<div className="font-semibold">Nicolas Beaussart</div>
<div className="text-slate-500">
Staff Platform Engineer, Payfit
</div>
</div>
<PayfitIcon
aria-hidden="true"
className="ml-auto size-10 shrink-0 text-[#0F6FDE]"
/>
</figcaption>
</figure>
<figure className="mt-16 flex flex-col justify-between rounded-lg bg-white p-4 pl-8 dark:bg-slate-950">
<blockquote className="text-base/7">
<p>
Nx means tooling and efficiency around our software development
lifecycle that empowers us to move a lot faster, ship code faster
and more reliably.
</p>
</blockquote>
<figcaption className="mt-6 flex items-center gap-x-4 text-sm/6">
<img
alt="Justin Schwartzenberger, Principal Software Engineer, SiriusXM"
src="https://avatars.githubusercontent.com/u/1243236?v=4"
className="size-8 flex-none rounded-full"
/>
<div>
<div className="font-semibold">Justin Schwartzenberger</div>
<div className="text-slate-500">
Principal Software Engineer, SiriusXM
</div>
</div>
<SiriusxmAlternateIcon
aria-hidden="true"
className="ml-auto size-10 shrink-0 rounded text-[#0000EB] dark:bg-slate-200"
/>
</figcaption>
</figure>
<figure className="mt-16 flex flex-col justify-between rounded-lg bg-white p-4 pl-8 dark:bg-slate-950">
<blockquote className="text-base/7">
<p>
"We leverage Nx to share code, UX, and styles. All teams decided
to migrate their frontend code to it. We then moved a backend app
in, and devs loved it so now every apps there."
</p>
</blockquote>
<figcaption className="mt-6 flex items-center gap-x-4 text-sm/6">
<img
alt="Amir Toole, VP of Engineering, Caseware"
src="/images/customers/enterprise/amir-toole-caseware-headshot.avif"
className="size-8 flex-none rounded-full"
/>
<div>
<div className="font-semibold">Amir Toole</div>
<div className="text-slate-500">VP of Engineering, Caseware</div>
</div>
<CasewareIcon
aria-hidden="true"
className="ml-auto size-10 text-[#F56354]"
/>
</figcaption>
</figure>
</div>
</div>
);
}

View File

@ -0,0 +1,99 @@
import {
BoltIcon,
CheckCircleIcon,
LightBulbIcon,
} from '@heroicons/react/24/outline';
import { ReactElement } from 'react';
import { SectionHeading } from '@nx/nx-dev/ui-common';
import Link from 'next/link';
const features = [
{
name: 'Reduce CI waste',
description: (
<>
<p className="flex-auto">
Speed up pipelines with caching, task splitting, automatic flaky tasks
retries, and smart distribution.
</p>
<div className="mt-4">
<Link
href="/ci/intro/ci-with-nx"
title="Learn how to speed up CI"
className="text-sm/6 font-semibold"
>
Learn how to speed up CI <span aria-hidden="true"></span>
</Link>
</div>
</>
),
icon: BoltIcon,
},
{
name: 'Fewer incorrect implementations',
description: (
<>
<p className="flex-auto">
Tight feedback loops and shared context enable teams to make smaller,
better-timed changes that land right the first time.
</p>
</>
),
icon: CheckCircleIcon,
},
{
name: 'Speed up decision-making with AI',
description: (
<>
<p className="flex-auto">
Derive project graphs to reveal architectural context and change
impact cross-repo so teams can move quicklyand with confidence.
</p>
</>
),
icon: LightBulbIcon,
},
];
export function CutDownEngineeringWaste(): ReactElement {
return (
<div
id="cut-down-engineering-waste"
className="mx-auto max-w-7xl scroll-mt-32 px-6 lg:px-8"
>
<div className="mx-auto max-w-2xl lg:mx-0">
<div className="h-8 w-36 border-t-2 border-green-500" />
<SectionHeading
as="h2"
variant="title"
id="cut-down-engineering-waste-title"
>
Cut Down Engineering Waste
</SectionHeading>
<SectionHeading as="p" variant="subtitle" className="mt-6">
Prevent issues before they become months-long rework.
</SectionHeading>
</div>
<div className="mx-auto mt-16 max-w-2xl sm:mt-20 lg:mt-24 lg:max-w-none">
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-16 lg:max-w-none lg:grid-cols-3">
{features.map((feature) => (
<div key={feature.name} className="flex flex-col">
<dt className="text-base/7 font-semibold">
<div className="mb-6 flex size-10 items-center justify-center rounded-lg bg-green-500">
<feature.icon
aria-hidden="true"
className="size-6 text-white"
/>
</div>
{feature.name}
</dt>
<dd className="mt-1 flex flex-auto flex-col text-base/7">
{feature.description}
</dd>
</div>
))}
</dl>
</div>
</div>
);
}

View File

@ -0,0 +1,113 @@
import {
ArrowsRightLeftIcon,
ShieldCheckIcon,
SparklesIcon,
} from '@heroicons/react/24/outline';
import { ReactElement } from 'react';
import { SectionHeading } from '@nx/nx-dev/ui-common';
import Link from 'next/link';
const features = [
{
name: 'Enable developer mobility',
description: (
<p className="flex-auto">
Standardized practices and shared architectural context make it easy for
engineers to onboard quickly and increase dev mobility across projects
and teams.
</p>
),
icon: ArrowsRightLeftIcon,
},
{
name: 'Define and enforce standards',
description: (
<>
<p className="flex-auto">
Establish best practices once and propagate them across teams with{' '}
<Link
href="/ci/recipes/enterprise/conformance/publish-conformance-rules-to-nx-cloud#publish-conformance-rules-to-nx-cloud"
title="Nx Conformance rules"
prefetch={false}
className="underline"
>
Conformance rules
</Link>
.
</p>
<div className="mt-4">
<Link
href="/ci/recipes/enterprise/conformance/publish-conformance-rules-to-nx-cloud#publish-conformance-rules-to-nx-cloud"
title="Learn more about Nx Conformance rules"
className="text-sm/6 font-semibold"
>
Learn more about Nx Conformance rules{' '}
<span aria-hidden="true"></span>
</Link>
</div>
</>
),
icon: ShieldCheckIcon,
},
{
name: 'Align knowledge across teams with smarter AI',
description: (
<>
<p className="flex-auto">
Use Nxs MCP server to ensure every engineer and LLM operates from the
same source of truth.
</p>
<div className="mt-4">
<Link
href="/features/enhance-AI"
title="Learn about Enhancing your LLM"
className="text-sm/6 font-semibold"
>
Learn about Enhancing your LLM <span aria-hidden="true"></span>
</Link>
</div>
</>
),
icon: SparklesIcon,
},
];
export function KeepTeamsAligned(): ReactElement {
return (
<div
id="keep-teams-aligned"
className="mx-auto max-w-7xl scroll-mt-32 px-6 lg:px-8"
>
<div className="mx-auto max-w-2xl lg:mx-0">
<div className="h-8 w-36 border-t-2 border-blue-500 dark:border-sky-500" />
<SectionHeading as="h2" variant="title" id="keep-teams-aligned-title">
Keep Teams Aligned
</SectionHeading>
<SectionHeading as="p" variant="subtitle" className="mt-6">
Standardization shouldnt slow you downit should free you to move
faster.
</SectionHeading>
</div>
<div className="mx-auto mt-16 max-w-2xl sm:mt-20 lg:mt-24 lg:max-w-none">
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-16 lg:max-w-none lg:grid-cols-3">
{features.map((feature) => (
<div key={feature.name} className="flex flex-col">
<dt className="text-base/7 font-semibold">
<div className="mb-6 flex size-10 items-center justify-center rounded-lg bg-blue-500 dark:bg-sky-500">
<feature.icon
aria-hidden="true"
className="size-6 text-white"
/>
</div>
{feature.name}
</dt>
<dd className="mt-1 flex flex-auto flex-col text-base/7">
{feature.description}
</dd>
</div>
))}
</dl>
</div>
</div>
);
}

View File

@ -0,0 +1,84 @@
import {
EyeIcon,
LinkIcon,
RocketLaunchIcon,
} from '@heroicons/react/24/outline';
import { ReactElement } from 'react';
import { SectionHeading } from '@nx/nx-dev/ui-common';
const features = [
{
name: 'Execute large, cross-team changes',
description: (
<p className="flex-auto">
Coordinate and fully automate updates across multiple repositories,
teams, or lines of business without slowing down.
</p>
),
icon: RocketLaunchIcon,
},
{
name: 'Break down silos',
description: (
<>
<p className="flex-auto">
Enable developers to work across teams more effectively and reuse code
confidently.
</p>
</>
),
icon: LinkIcon,
},
{
name: 'Understand impact across teams',
description: (
<>
<p className="flex-auto">
Understand where shared libraries are used and how changes impact
other teams.
</p>
</>
),
icon: EyeIcon,
},
];
export function ScaleWithEase(): ReactElement {
return (
<div
id="scale-with-ease"
className="mx-auto max-w-7xl scroll-mt-32 px-6 lg:px-8"
>
<div className="mx-auto max-w-2xl lg:mx-0">
<div className="h-8 w-36 border-t-2 border-pink-500 dark:border-fuchsia-500" />
<SectionHeading as="h2" variant="title" id="scale-with-ease-title">
Scale With Ease
</SectionHeading>
<SectionHeading as="p" variant="subtitle" className="mt-6">
Your org is growing. Keep delivery velocity high without getting
bogged down by team growth.
</SectionHeading>
</div>
<div className="mx-auto mt-16 max-w-2xl sm:mt-20 lg:mt-24 lg:max-w-none">
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-16 lg:max-w-none lg:grid-cols-3">
{features.map((feature) => (
<div key={feature.name} className="flex flex-col">
<dt className="text-base/7 font-semibold">
<div className="mb-6 flex size-10 items-center justify-center rounded-lg bg-pink-500 dark:bg-fuchsia-500">
<feature.icon
aria-hidden="true"
className="size-6 text-white"
/>
</div>
{feature.name}
</dt>
<dd className="mt-1 flex flex-auto flex-col text-base/7">
{feature.description}
</dd>
</div>
))}
</dl>
</div>
</div>
);
}

View File

@ -0,0 +1,206 @@
import { ComponentProps, ReactElement, useState } from 'react';
import { ButtonLink, SectionHeading, VideoModal } from '@nx/nx-dev/ui-common';
import { sendCustomEvent } from '@nx/nx-dev/feature-analytics';
import {
ChevronRightIcon,
EnvelopeIcon,
PlayIcon,
} from '@heroicons/react/24/outline';
import Image from 'next/image';
import { UkgIcon } from '@nx/nx-dev/ui-icons';
import { cx } from '@nx/nx-dev/ui-primitives';
import { MovingBorder } from '@nx/nx-dev/ui-animations';
import { motion } from 'framer-motion';
function PlayButton({
className,
...props
}: ComponentProps<'div'>): ReactElement {
const parent = {
initial: {
width: 82,
transition: {
when: 'afterChildren',
},
},
hover: {
width: 296,
transition: {
duration: 0.125,
type: 'tween',
ease: 'easeOut',
},
},
};
const child = {
initial: {
opacity: 0,
x: -6,
},
hover: {
x: 0,
opacity: 1,
transition: {
duration: 0.015,
type: 'tween',
ease: 'easeOut',
},
},
};
return (
<div
className={cx(
'group relative overflow-hidden rounded-full bg-transparent p-[1px] shadow-md',
className
)}
{...props}
>
<div className="absolute inset-0">
<MovingBorder duration={5000} rx="5%" ry="5%">
<div className="size-20 bg-[radial-gradient(var(--blue-500)_40%,transparent_60%)] opacity-[0.8] dark:bg-[radial-gradient(var(--pink-500)_40%,transparent_60%)]" />
</MovingBorder>
</div>
<motion.div
initial="initial"
whileHover="hover"
variants={parent}
className="relative isolate flex size-20 cursor-pointer items-center justify-center gap-6 rounded-full border-2 border-slate-100 bg-white/10 p-6 text-white antialiased backdrop-blur-xl"
>
<PlayIcon aria-hidden="true" className="absolute left-6 top-6 size-8" />
<motion.div variants={child} className="absolute left-20 top-4 w-48">
<p className="text-base font-medium">Watch the interview</p>
<p className="text-xs">Under 3 minutes.</p>
</motion.div>
</motion.div>
</div>
);
}
export function SolutionsManagementHero(): ReactElement {
const [isOpen, setIsOpen] = useState(false);
return (
<section className="relative overflow-hidden">
<div className="mx-auto max-w-7xl lg:flex">
<div className="mx-auto max-w-3xl px-6 py-24 lg:mx-0 lg:shrink-0 lg:px-8">
<p>
<a
href="https://bit.ly/4jQLCqp"
title="See live event in details"
className="group/event-link inline-flex space-x-6"
>
<span className="rounded-full bg-blue-600/10 px-3 py-1 text-sm/6 font-semibold text-blue-600 ring-1 ring-inset ring-blue-600/10 dark:bg-cyan-600/10 dark:text-cyan-600 dark:ring-cyan-600/10">
Live event
</span>
<span className="inline-flex items-center space-x-2 text-sm/6 font-medium">
<span>Webinar + live Q&A on May 28th</span>
<ChevronRightIcon
aria-hidden="true"
className="size-5 transform transition-all group-hover/event-link:translate-x-1"
/>
</span>
</a>
</p>
<SectionHeading
id="get-speed-and-scale"
as="h1"
variant="display"
className="mt-8 text-pretty tracking-tight"
>
Standardize, scale,{' '}
<span className="rounded-lg bg-gradient-to-r from-blue-500 to-sky-500 bg-clip-text text-transparent">
ship faster with less waste
</span>
</SectionHeading>
<SectionHeading
as="p"
variant="subtitle"
className="mx-auto mt-6 max-w-3xl lg:pr-20"
>
Build, test, and deploy software more efficiently with powerful repo
tools and intelligent CI, freeing your teams to innovate faster.
</SectionHeading>
<div className="mt-8 flex items-center gap-x-3">
<ButtonLink
href="/contact/sales"
title="Talk to our team"
variant="primary"
size="default"
onClick={() =>
sendCustomEvent(
'contact-sales-click',
'solutions-engineering-hero',
'solutions-engineering'
)
}
>
Talk to our team
</ButtonLink>
<ButtonLink
href="https://go.nx.dev/nx-newsletter"
title="Talk to the team"
variant="secondary"
size="default"
onClick={() =>
sendCustomEvent(
'contact-sales-click',
'solutions-engineering-hero',
'solutions-engineering'
)
}
>
<EnvelopeIcon aria-hidden="true" className="size-4" />
<span>Subscribe to the newsletter</span>
</ButtonLink>
</div>
</div>
<div className="flex items-center justify-end">
<div>
<div className="relative">
<Image
src="/images/customers/video-story-ukg.avif"
alt="video still"
width={960}
height={540}
loading="lazy"
unoptimized
className="relative rounded-xl"
/>
<div className="absolute inset-0 grid h-full w-full items-center justify-center">
<PlayButton
onClick={() => {
setIsOpen(true);
sendCustomEvent(
'ukg-testimonial-video-click',
'ukg-testimonial-solutions',
'solutions'
);
}}
/>
</div>
</div>
<div className="mt-4 flex items-center gap-x-4 text-sm/6">
<UkgIcon
aria-hidden="true"
className="size-10 flex-none shrink-0 text-[#005151] dark:text-white"
/>
<div>
Discover how UKG reduced build times while scaling development
across teams with Nx.
</div>
</div>
</div>
<VideoModal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
videoUrl="https://youtu.be/rSC8wihnfP4"
/>
</div>
</div>
</section>
);
}

View File

@ -0,0 +1,104 @@
import type { ReactElement } from 'react';
import {
HetznerCloudIcon,
PayfitIcon,
SiriusxmAlternateIcon,
} from '@nx/nx-dev/ui-icons';
import { SectionHeading } from '@nx/nx-dev/ui-common';
export function SolutionsManagementTestimonials(): ReactElement {
return (
<div className="border border-slate-100 bg-slate-50 px-6 py-24 sm:px-6 sm:py-32 lg:px-8 dark:border-slate-900 dark:bg-slate-900/[0.8]">
<div className="mx-auto max-w-5xl text-center">
<SectionHeading as="h2" variant="title" id="testimonials">
Hear from developers like you
</SectionHeading>
<SectionHeading as="p" variant="subtitle" className="mt-6">
Don't just take our word for it. See how Nx transforms development for
teams worldwide.
</SectionHeading>
</div>
<div className="mx-auto grid max-w-7xl gap-8 lg:grid-cols-3">
<figure className="mt-16 flex flex-col justify-between rounded-lg bg-white p-4 pl-8 dark:bg-slate-950">
<blockquote className="text-base/7">
<p>
Nx means tooling and efficiency around our software development
lifecycle that empowers us to move a lot faster, ship code faster
and more reliably.
</p>
</blockquote>
<figcaption className="mt-6 flex items-center gap-x-4 text-sm/6">
<img
alt="Justin Schwartzenberger, Principal Software Engineer, SiriusXM"
src="https://avatars.githubusercontent.com/u/1243236?v=4"
className="size-8 flex-none rounded-full"
/>
<div>
<div className="font-semibold">Justin Schwartzenberger</div>
<div className="text-slate-500">
Principal Software Engineer, SiriusXM
</div>
</div>
<SiriusxmAlternateIcon
aria-hidden="true"
className="ml-auto size-10 shrink-0 rounded text-[#0000EB] dark:bg-slate-200"
/>
</figcaption>
</figure>
<figure className="mt-16 flex flex-col justify-between rounded-lg bg-white p-4 pl-8 dark:bg-slate-950">
<blockquote className="text-base/7">
<p>
"A year ago, to deploy a feature, it took 2-5 days. Now the same
feature takes 2 hours. We use Nx Cloud to speed up CI. Without it,
we couldnt have the velocity that we have right now."
</p>
</blockquote>
<figcaption className="mt-6 flex items-center gap-x-4 text-sm/6">
<img
alt="Nicolas Beaussart, Staff Platform Engineer, Payfit"
src="https://avatars.githubusercontent.com/u/7281023?v=4"
className="size-8 flex-none rounded-full"
/>
<div>
<div className="font-semibold">Nicolas Beaussart</div>
<div className="text-slate-500">
Staff Platform Engineer, Payfit
</div>
</div>
<PayfitIcon
aria-hidden="true"
className="ml-auto size-10 shrink-0 text-[#0F6FDE]"
/>
</figcaption>
</figure>
<figure className="mt-16 flex flex-col justify-between rounded-lg bg-white p-4 pl-8 dark:bg-slate-950">
<blockquote className="text-base/7">
<p>
"Nx is speed and scalability - with the set of features we had 3
years ago and CI being kind of slow, now we have way more features
and CI is fast in comparison. Thats a huge win for us."
</p>
</blockquote>
<figcaption className="mt-6 flex items-center gap-x-4 text-sm/6">
<img
alt="Pavlo Grosse, Senior Software Engineer, Hetzner Cloud"
src="https://avatars.githubusercontent.com/u/2219064?v=4"
className="size-8 flex-none rounded-full"
/>
<div>
<div className="font-semibold">Pavlo Grosse</div>
<div className="text-slate-500">
Senior Engineer, Hetzner Cloud
</div>
</div>
<HetznerCloudIcon
aria-hidden="true"
className="mx-auto size-10 flex-none shrink-0 bg-white text-[#D50C2D]"
/>
</figcaption>
</figure>
</div>
</div>
);
}

View File

@ -0,0 +1,105 @@
import {
AdjustmentsHorizontalIcon,
FunnelIcon,
ServerStackIcon,
} from '@heroicons/react/24/outline';
import { ReactElement } from 'react';
import { SectionHeading } from '@nx/nx-dev/ui-common';
import Link from 'next/link';
const features = [
{
name: 'Use only what is needed',
description: (
<p className="flex-auto">
Nx runs only{' '}
<Link
href="/ci/features/affected"
title="Nx affected tasks"
prefetch={false}
className="underline"
>
affected tasks
</Link>{' '}
and caches results to cut down compute usage.
</p>
),
icon: FunnelIcon,
},
{
name: 'Smarter compute distribution',
description: (
<>
<p className="flex-auto">
Dynamically allocate just the right number of efficient sized machines
to get good performance and avoid over-provisioning.
</p>
<div className="mt-4">
<Link
href="/ci/features/distribute-task-execution"
title="Learn about Nx Agents"
className="text-sm/6 font-semibold"
>
Learn about Nx Agents <span aria-hidden="true"></span>
</Link>
</div>
</>
),
icon: AdjustmentsHorizontalIcon,
},
{
name: 'Reliable execution on flexible infrastructure',
description: (
<>
<p className="flex-auto">
Run CI on spot instances or other low-cost infrastructure without
sacrificing stability.
</p>
</>
),
icon: ServerStackIcon,
},
];
export function CostEfficientCompute(): ReactElement {
return (
<div
id="cost-efficient-compute-without-sacrificing-speed"
className="mx-auto max-w-7xl scroll-mt-32 px-6 lg:px-8"
>
<div className="mx-auto max-w-2xl lg:mx-0">
<div className="h-8 w-36 border-t-2 border-green-500" />
<SectionHeading
as="h2"
variant="title"
id="cost-efficient-compute-without-sacrificing-speed-title"
>
Cost-Efficient Compute Without Sacrificing Speed
</SectionHeading>
<SectionHeading as="p" variant="subtitle" className="mt-6">
Reduce infrastructure costs without compromising performance.
</SectionHeading>
</div>
<div className="mx-auto mt-16 max-w-2xl sm:mt-20 lg:mt-24 lg:max-w-none">
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-16 lg:max-w-none lg:grid-cols-3">
{features.map((feature) => (
<div key={feature.name} className="flex flex-col">
<dt className="text-base/7 font-semibold">
<div className="mb-6 flex size-10 items-center justify-center rounded-lg bg-green-500">
<feature.icon
aria-hidden="true"
className="size-6 text-white"
/>
</div>
{feature.name}
</dt>
<dd className="mt-1 flex flex-auto flex-col text-base/7">
{feature.description}
</dd>
</div>
))}
</dl>
</div>
</div>
);
}

View File

@ -0,0 +1,114 @@
import {
ArchiveBoxIcon,
LinkIcon,
ScaleIcon,
ShieldCheckIcon,
} from '@heroicons/react/24/outline';
import { ReactElement } from 'react';
import { SectionHeading } from '@nx/nx-dev/ui-common';
import Link from 'next/link';
const features = [
{
name: 'Simple CI, out of the box',
description: (
<>
<p className="flex-auto">
Reduce maintenance for platform teams and avoid tech debt with
built-in solutions that work across projects and repos.
</p>
</>
),
icon: ArchiveBoxIcon,
},
{
name: 'Easy integration with existing tools',
description: (
<>
<p className="flex-auto">
Seamlessly integrate with any repo structure and CI provider.
</p>
<div className="mt-4">
<Link
href="/ci/intro/ci-with-nx"
title="Get started with your existing CI provider"
prefetch={false}
className="text-sm/6 font-semibold"
>
Get started with your existing CI provider
<span aria-hidden="true"></span>
</Link>
</div>
</>
),
icon: LinkIcon,
},
{
name: 'Standardize and refactor at scale',
description: (
<>
<p className="flex-auto">
Use Polygraph to gain visibility of dependencies across teams and
repos, enforce conformance rules, and easily roll out updates across
all repos.
</p>
</>
),
icon: ScaleIcon,
},
{
name: 'Reliable pipelines, fewer headaches',
description: (
<>
<p className="flex-auto">
Get consistent CI runs with less flakiness and better performance.
</p>
</>
),
icon: ShieldCheckIcon,
},
];
export function EasyToAdoptEasyToMaintain(): ReactElement {
return (
<div
id="easy-to-adopt-easy-to-maintain"
className="mx-auto max-w-7xl scroll-mt-32 px-6 lg:px-8"
>
<div className="mx-auto max-w-2xl lg:mx-0">
<div className="h-8 w-36 border-t-2 border-blue-500 dark:border-sky-500" />
<SectionHeading
as="h2"
variant="title"
id="easy-to-adopt-easy-to-maintain-title"
>
Easy to Adopt, Easy to Maintain
</SectionHeading>
<SectionHeading as="p" variant="subtitle" className="mt-6">
Your team shouldn't have to build developer infrastructure from
scratch.
</SectionHeading>
</div>
<div className="mx-auto mt-16 max-w-2xl sm:mt-20 lg:mt-24 lg:max-w-none">
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-16 lg:max-w-none lg:grid-cols-2">
{features.map((feature) => (
<div key={feature.name} className="flex flex-col">
<dt className="text-base/7 font-semibold">
<div className="mb-6 flex size-10 items-center justify-center rounded-lg bg-blue-500 dark:bg-sky-500">
<feature.icon
aria-hidden="true"
className="size-6 text-white"
/>
</div>
{feature.name}
</dt>
<dd className="mt-1 flex flex-auto flex-col text-base/7">
{feature.description}
</dd>
</div>
))}
</dl>
</div>
</div>
);
}

View File

@ -0,0 +1,116 @@
import {
ArrowPathIcon,
BoltIcon,
ShieldExclamationIcon,
} from '@heroicons/react/24/outline';
import { ReactElement } from 'react';
import { SectionHeading } from '@nx/nx-dev/ui-common';
import Link from 'next/link';
const features = [
{
name: 'Better security posture',
description: (
<>
<p className="flex-auto">
Quickly identify and address vulnerabilities with Polygraphs
cross-repo visibility, and enforce consistent, enterprise-grade
security standards across teams.
</p>
<div className="mt-4">
<Link
href="/enterprise/security"
title="Learn about our Enterprise Grade Security"
className="text-sm/6 font-semibold"
>
Learn about our Enterprise Grade Security{' '}
<span aria-hidden="true"></span>
</Link>
</div>
</>
),
icon: ShieldExclamationIcon,
},
{
name: 'Reduce CI waste',
description: (
<>
<p className="flex-auto">
Speed up pipelines with caching, task splitting, automatic flaky tasks
retries, and smart distribution.
</p>
<div className="mt-4">
<Link
href="/ci/intro/ci-with-nx"
title="Learn how to speed up CI"
prefetch={false}
className="text-sm/6 font-semibold"
>
Learn how to speed up CI <span aria-hidden="true"></span>
</Link>
</div>
</>
),
icon: BoltIcon,
},
{
name: 'Automatic flaky task handling',
description: (
<>
<p className="flex-auto">
Unstable tasks are automatically detected and re-run, so developers
dont waste time on false failures.
</p>
<div className="mt-4">
<Link
href="/ci/features/flaky-tasks"
title="Learn about Flaky Task Retries"
className="text-sm/6 font-semibold"
>
Learn about Flaky Task Retries <span aria-hidden="true"></span>
</Link>
</div>
</>
),
icon: ArrowPathIcon,
},
];
export function ReliableByDesign(): ReactElement {
return (
<div
id="reliable-by-design"
className="mx-auto max-w-7xl scroll-mt-32 px-6 lg:px-8"
>
<div className="mx-auto max-w-2xl lg:mx-0">
<div className="h-8 w-36 border-t-2 border-pink-500 dark:border-fuchsia-500" />
<SectionHeading as="h2" variant="title" id="reliable-by-design-title">
Reliable by Design
</SectionHeading>
<SectionHeading as="p" variant="subtitle" className="mt-6">
Fewer incidents. Less fire-fighting.
</SectionHeading>
</div>
<div className="mx-auto mt-16 max-w-2xl sm:mt-20 lg:mt-24 lg:max-w-none">
<dl className="grid max-w-xl grid-cols-1 gap-x-8 gap-y-16 lg:max-w-none lg:grid-cols-3">
{features.map((feature) => (
<div key={feature.name} className="flex flex-col">
<dt className="text-base/7 font-semibold">
<div className="mb-6 flex size-10 items-center justify-center rounded-lg bg-pink-500 dark:bg-fuchsia-500">
<feature.icon
aria-hidden="true"
className="size-6 text-white"
/>
</div>
{feature.name}
</dt>
<dd className="mt-1 flex flex-auto flex-col text-base/7">
{feature.description}
</dd>
</div>
))}
</dl>
</div>
</div>
);
}

View File

@ -0,0 +1,207 @@
import { ComponentProps, ReactElement, useState } from 'react';
import { ButtonLink, SectionHeading, VideoModal } from '@nx/nx-dev/ui-common';
import { sendCustomEvent } from '@nx/nx-dev/feature-analytics';
import {
ChevronRightIcon,
EnvelopeIcon,
PlayIcon,
} from '@heroicons/react/24/outline';
import { PayfitIcon } from '@nx/nx-dev/ui-icons';
import { cx } from '@nx/nx-dev/ui-primitives';
import { MovingBorder } from '@nx/nx-dev/ui-animations';
import { motion } from 'framer-motion';
import Image from 'next/image';
function PlayButton({
className,
...props
}: ComponentProps<'div'>): ReactElement {
const parent = {
initial: {
width: 82,
transition: {
when: 'afterChildren',
},
},
hover: {
width: 296,
transition: {
duration: 0.125,
type: 'tween',
ease: 'easeOut',
},
},
};
const child = {
initial: {
opacity: 0,
x: -6,
},
hover: {
x: 0,
opacity: 1,
transition: {
duration: 0.015,
type: 'tween',
ease: 'easeOut',
},
},
};
return (
<div
className={cx(
'group relative overflow-hidden rounded-full bg-transparent p-[1px] shadow-md',
className
)}
{...props}
>
<div className="absolute inset-0">
<MovingBorder duration={5000} rx="5%" ry="5%">
<div className="size-20 bg-[radial-gradient(var(--blue-500)_40%,transparent_60%)] opacity-[0.8] dark:bg-[radial-gradient(var(--pink-500)_40%,transparent_60%)]" />
</MovingBorder>
</div>
<motion.div
initial="initial"
whileHover="hover"
variants={parent}
className="relative isolate flex size-20 cursor-pointer items-center justify-center gap-6 rounded-full border-2 border-slate-100 bg-white/10 p-6 text-white antialiased backdrop-blur-xl"
>
<PlayIcon aria-hidden="true" className="absolute left-6 top-6 size-8" />
<motion.div variants={child} className="absolute left-20 top-4 w-48">
<p className="text-base font-medium">Watch the interview</p>
<p className="text-xs">Under 3 minutes.</p>
</motion.div>
</motion.div>
</div>
);
}
export function SolutionsPlatformHero(): ReactElement {
const [isOpen, setIsOpen] = useState(false);
return (
<section className="relative overflow-hidden">
<div className="mx-auto max-w-7xl lg:flex">
<div className="mx-auto max-w-3xl px-6 py-24 lg:mx-0 lg:shrink-0 lg:px-8">
<p>
<a
href="https://bit.ly/4jQLCqp"
title="See live event in details"
className="group/event-link inline-flex space-x-6"
>
<span className="rounded-full bg-blue-600/10 px-3 py-1 text-sm/6 font-semibold text-blue-600 ring-1 ring-inset ring-blue-600/10 dark:bg-cyan-600/10 dark:text-cyan-600 dark:ring-cyan-600/10">
Live event
</span>
<span className="inline-flex items-center space-x-2 text-sm/6 font-medium">
<span>Webinar + live Q&A on May 28th</span>
<ChevronRightIcon
aria-hidden="true"
className="size-5 transform transition-all group-hover/event-link:translate-x-1"
/>
</span>
</a>
</p>
<SectionHeading
id="get-speed-and-scale"
as="h1"
variant="display"
className="mt-8 text-pretty tracking-tight"
>
CI that works out of the box {' '}
<span className="rounded-lg bg-gradient-to-r from-blue-500 to-sky-500 bg-clip-text text-transparent">
stays reliable at scale
</span>
</SectionHeading>
<SectionHeading
as="p"
variant="subtitle"
className="mx-auto mt-6 max-w-3xl lg:pr-20"
>
Reliable, out-of-the-box CI that scales. Cut costs and boost speed
with smart caching, compute distribution, and enhanced security for
your pipelines.
</SectionHeading>
<div className="mt-8 flex items-center gap-x-3">
<ButtonLink
href="/contact/sales"
title="Talk to our team"
variant="primary"
size="default"
onClick={() =>
sendCustomEvent(
'contact-sales-click',
'solutions-platform-hero',
'solutions-platform'
)
}
>
Talk to our team
</ButtonLink>
<ButtonLink
href="https://go.nx.dev/nx-newsletter"
title="Talk to the team"
variant="secondary"
size="default"
onClick={() =>
sendCustomEvent(
'contact-sales-click',
'solutions-platform-hero',
'solutions-platform'
)
}
>
<EnvelopeIcon aria-hidden="true" className="size-4" />
<span>Subscribe to the newsletter</span>
</ButtonLink>
</div>
</div>
<div className="flex items-center justify-end">
<div>
<div className="relative">
<Image
src="/images/customers/video-story-payfit.avif"
alt="video still"
width={960}
height={540}
loading="lazy"
unoptimized
className="relative rounded-xl"
/>
<div className="absolute inset-0 grid h-full w-full items-center justify-center">
<PlayButton
onClick={() => {
setIsOpen(true);
sendCustomEvent(
'payfit-testimonial-video-click',
'payfit-testimonial-solutions',
'solutions'
);
}}
/>
</div>
</div>
<div className="mt-4 flex items-center gap-x-4 text-sm/6">
<PayfitIcon
aria-hidden="true"
className="size-10 flex-none shrink-0 text-[#0F6FDE] dark:text-white"
/>
<div>
From 5 days to 2 hours: How Payfit improved velocity and
offloads complexity with Nx.
</div>
</div>
</div>
<VideoModal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
videoUrl="https://youtu.be/Vdk-tza4PCs"
/>
</div>
</div>
</section>
);
}

View File

@ -0,0 +1,103 @@
import type { ReactElement } from 'react';
import {
CasewareIcon,
PayfitIcon,
SiriusxmAlternateIcon,
UkgIcon,
} from '@nx/nx-dev/ui-icons';
import { SectionHeading } from '@nx/nx-dev/ui-common';
export function SolutionsPlatformTestimonials(): ReactElement {
return (
<div className="border border-slate-100 bg-slate-50 px-6 py-24 sm:px-6 sm:py-32 lg:px-8 dark:border-slate-900 dark:bg-slate-900/[0.8]">
<div className="mx-auto max-w-5xl text-center">
<SectionHeading as="h2" variant="title" id="testimonials">
Hear from developers like you
</SectionHeading>
<SectionHeading as="p" variant="subtitle" className="mt-6">
Don't just take our word for it. See how Nx transforms development for
teams worldwide.
</SectionHeading>
</div>
<div className="mx-auto grid max-w-7xl gap-12 lg:grid-cols-3">
<figure className="mt-16 flex flex-col justify-between rounded-lg bg-white p-4 pl-8 dark:bg-slate-950">
<blockquote className="text-base/7">
<p>
Nx means tooling and efficiency around our software development
lifecycle that empowers us to move a lot faster, ship code faster
and more reliably.
</p>
</blockquote>
<figcaption className="mt-6 flex items-center gap-x-4 text-sm/6">
<img
alt="Justin Schwartzenberger, Principal Software Engineer, SiriusXM"
src="https://avatars.githubusercontent.com/u/1243236?v=4"
className="size-8 flex-none rounded-full"
/>
<div>
<div className="font-semibold">Justin Schwartzenberger</div>
<div className="text-slate-500">
Principal Software Engineer, SiriusXM
</div>
</div>
<SiriusxmAlternateIcon
aria-hidden="true"
className="ml-auto size-10 rounded text-[#0000EB] dark:bg-slate-200"
/>
</figcaption>
</figure>
<figure className="mt-16 flex flex-col justify-between rounded-lg bg-white p-4 pl-8 dark:bg-slate-950">
<blockquote className="text-base/7">
<p>
"A year ago, to deploy a feature, it took 2-5 days. Now the same
feature takes 2 hours. We use Nx Cloud to speed up CI. Without it,
we couldnt have the velocity that we have right now."
</p>
</blockquote>
<figcaption className="mt-6 flex items-center gap-x-4 text-sm/6">
<img
alt="Nicolas Beaussart, Staff Platform Engineer, Payfit"
src="https://avatars.githubusercontent.com/u/7281023?v=4"
className="size-8 flex-none rounded-full"
/>
<div>
<div className="font-semibold">Nicolas Beaussart</div>
<div className="text-slate-500">
Staff Platform Engineer, Payfit
</div>
</div>
<PayfitIcon
aria-hidden="true"
className="ml-auto size-10 text-[#0F6FDE]"
/>
</figcaption>
</figure>
<figure className="mt-16 flex flex-col justify-between rounded-lg bg-white p-4 pl-8 dark:bg-slate-950">
<blockquote className="text-base/7">
<p>
We got requests from other feature teams saying they wanted to
build an experience to deploy on mobile and web. With Nx we can
share libraries so they can build on top of what weve already
built and reduce code duplication.
</p>
</blockquote>
<figcaption className="mt-6 flex items-center gap-x-4 text-sm/6">
<img
alt="Sid Govindaraju, Engineering Manager, UKG"
src="https://media.licdn.com/dms/image/v2/C4D03AQH0wxtNq8Brhw/profile-displayphoto-shrink_200_200/profile-displayphoto-shrink_200_200/0/1639897842208?e=2147483647&v=beta&t=wPVxARsxwab6nvYv6DrsP1XnjsUksa2Nmx5kPlp2ny8"
className="size-8 flex-none rounded-full"
/>
<div>
<div className="font-semibold">Sid Govindaraju</div>
<div className="text-slate-500">Engineering Manager, UKG</div>
</div>
<UkgIcon
aria-hidden="true"
className="ml-auto size-10 shrink-0 text-[#005151] dark:text-white"
/>
</figcaption>
</figure>
</div>
</div>
);
}

View File

@ -0,0 +1,89 @@
import Link from 'next/link';
import { ReactElement } from 'react';
import { sendCustomEvent } from '@nx/nx-dev/feature-analytics';
import { SectionHeading } from '@nx/nx-dev/ui-common';
export function SolutionsBottomCallToAction(): ReactElement {
return (
<section
className="relative isolate px-6 py-32 sm:py-40 lg:px-8"
aria-labelledby="section-cta-heading"
>
<svg
className="absolute inset-0 -z-10 h-full w-full rotate-180 stroke-black/10 [mask-image:radial-gradient(100%_100%_at_top_right,white,transparent)] dark:stroke-white/10"
aria-hidden="true"
focusable="false"
>
<defs>
<pattern
id="1d4240dd-898f-445f-932d-e2872fd12de3"
width={200}
height={200}
x="50%"
y={0}
patternUnits="userSpaceOnUse"
>
<path d="M.5 200V.5H200" fill="none" />
</pattern>
</defs>
<svg
x="50%"
y={0}
className="overflow-visible fill-slate-200/20 dark:fill-slate-800/20"
>
<path
d="M-200 0h201v201h-201Z M600 0h201v201h-201Z M-400 600h201v201h-201Z M200 800h201v201h-201Z"
strokeWidth={0}
/>
</svg>
<rect
width="100%"
height="100%"
strokeWidth={0}
fill="url(#1d4240dd-898f-445f-932d-e2872fd12de3)"
/>
</svg>
<div
className="absolute inset-x-0 top-10 -z-10 flex transform-gpu justify-center overflow-hidden blur-3xl"
aria-hidden="true"
>
<div
className="aspect-[1108/632] w-[69.25rem] flex-none bg-gradient-to-r from-[#80caff] to-[#4f46e5] opacity-10"
style={{
clipPath:
'polygon(73.6% 51.7%, 91.7% 11.8%, 100% 46.4%, 97.4% 82.2%, 92.5% 84.9%, 75.7% 64%, 55.3% 47.5%, 46.5% 49.4%, 45% 62.9%, 50.3% 87.2%, 21.3% 64.1%, 0.1% 100%, 5.4% 51.1%, 21.4% 63.9%, 58.9% 0.2%, 73.6% 51.7%)',
}}
/>
</div>
<div className="mx-auto max-w-5xl text-center">
<SectionHeading as="h2" variant="title" id="scale-your-organization">
Dont lose velocity as your organization grows{' '}
<br className="xl:block" />
<span className="line-through">10x developer</span>{' '}
<span className="rounded-lg bg-gradient-to-r from-cyan-500 to-blue-500 bg-clip-text text-transparent">
Nx developers are even more efficient at scale
</span>
</SectionHeading>
<div className="mt-10">
<p className="mt-6 italic">
<Link
href="/contact/sales"
title="Talk to our team"
prefetch={false}
onClick={() =>
sendCustomEvent(
'contact-team',
'enterprise-security-bottom-cta',
'enterprise-security'
)
}
className="rounded-md bg-slate-950 px-3.5 py-2.5 text-sm font-semibold text-slate-100 shadow-sm hover:bg-slate-800 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white dark:bg-white dark:text-slate-900 dark:hover:bg-slate-100"
>
Talk to our team
</Link>
</p>
</div>
</div>
</section>
);
}

View File

@ -0,0 +1,150 @@
'use client';
import {
Disclosure,
DisclosureButton,
DisclosurePanel,
Transition,
} from '@headlessui/react';
import { ChevronDownIcon } from '@heroicons/react/24/outline';
import { SectionHeading } from '@nx/nx-dev/ui-common';
import { cx } from '@nx/nx-dev/ui-primitives';
import { FAQPageJsonLd } from 'next-seo';
import Link from 'next/link';
import { ReactElement } from 'react';
export function SolutionsFaq(): ReactElement {
const faqs = [
{
question: 'What is Nx?',
answerJson:
'Nx is a smart build system and task orchestrator that understands how your code is built, used, and shared. It helps teams scale confidently by running only whats needed, enforcing best practices, and keeping builds fast and reliable—both locally and in CI. Nx also structures your metadata to power consistent, AI-assisted workflows across your entire development pipeline.',
answerUi: (
<p>
Nx is a smart build system and task orchestrator that understands how
your code is built, used, and shared. It helps teams scale confidently
by running only whats needed, enforcing best practices, and keeping
builds fast and reliableboth locally and in CI. Nx also structures
your metadata to power consistent, AI-assisted workflows across your
entire development pipeline.
</p>
),
},
{
question: 'Do I need to migrate to Nx all at once?',
answerJson:
'Not at all. Nx can be incrementally adopted. You can start with just your team and expand at your own pace.',
answerUi: (
<>
<p>
Not at all. Nx can be incrementally adopted. You can start with just
your team and expand at your own pace.
</p>
</>
),
},
{
question: 'Will Nx work with our current CI provider and tooling?',
answerJson:
'Yes. Nx integrates with all the major CI providers (GitHub Actions, CircleCI, GitLab, Azure, Bitbucket and Jenkins) and fits into your existing developer toolchain. You can easily get started with your existing stack.',
answerUi: (
<p>
Yes. Nx integrates with all the major CI providers (GitHub Actions,
CircleCI, GitLab, Azure, Bitbucket and Jenkins) and fits into your
existing developer toolchain. You can easily get started with your
existing stack.
</p>
),
},
{
question: 'Is Nx just for monorepos?',
answerJson:
'No. While Nx is well known in the monorepo community, it works just as well in polyrepo environments. Features like remote caching, dependency graphing, and conformance enforcement are valuable in any repo structure.',
answerUi: (
<p>
No. While Nx is well known in the monorepo community, it works just as
well in polyrepo environments. Features like remote caching,
dependency graphing, and conformance enforcement are valuable in any
repo structure.
</p>
),
},
];
return (
<section id="faq" className="scroll-mt-24">
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
<div className="lg:grid lg:grid-cols-3 lg:gap-8">
<header>
<SectionHeading as="h2" variant="title">
Have questions?
</SectionHeading>
<SectionHeading as="p" variant="subtitle" className="mt-6">
Got questions? We've got answers.
</SectionHeading>
<p className="text-md mt-4 text-slate-400 dark:text-slate-600">
<Link
href="/contact"
title="Reach out to the team"
className="font-semibold"
>
If you don't find what you're looking for, feel free to reach
out.
</Link>
</p>
</header>
<FAQPageJsonLd
useAppDir={true}
mainEntity={faqs.map((faq) => ({
questionName: faq.question,
acceptedAnswerText: faq.answerJson,
}))}
/>
<div className="mt-12 lg:col-span-2 lg:mt-0">
<dl className="mt-6 space-y-6 divide-y divide-slate-100 dark:divide-slate-800">
{faqs.map((faq) => (
<Disclosure as="div" key={faq.question} className="pt-6">
{({ open }) => (
<>
<dt className="text-lg">
<DisclosureButton className="flex w-full items-start justify-between text-left text-slate-400">
<span className="font-medium text-slate-800 dark:text-slate-300">
{faq.question}
</span>
<span className="ml-6 flex h-7 items-center">
<ChevronDownIcon
className={cx(
open ? '-rotate-180' : 'rotate-0',
'h-6 w-6 transform transition-transform'
)}
aria-hidden="true"
/>
</span>
</DisclosureButton>
</dt>
<Transition
enter="transition duration-100 ease-out"
enterFrom="transform -translate-y-6 opacity-0"
enterTo="transform translate-y-0 opacity-100"
leave="transition duration-75 ease-out"
leaveFrom="transform translate-y-0 opacity-100"
leaveTo="transform -translate-y-6 opacity-0"
>
<DisclosurePanel
as="dd"
className="mt-2 pr-12 text-base text-slate-500 dark:text-slate-400"
>
{faq.answerUi}
</DisclosurePanel>
</Transition>
</>
)}
</Disclosure>
))}
</dl>
</div>
</div>
</div>
</section>
);
}

View File

@ -0,0 +1,20 @@
import type { ReactElement } from 'react';
import { SectionHeading, Strong } from '@nx/nx-dev/ui-common';
export function SolutionsTopCallToAction(): ReactElement {
return (
<div className="border border-slate-100 bg-slate-50 px-6 py-24 sm:px-6 sm:py-32 lg:px-8 dark:border-slate-900 dark:bg-slate-900/[0.8]">
<div className="mx-auto max-w-3xl text-center">
<SectionHeading as="h2" variant="title" id="unlock-peak-performance">
Unlock Peak Performance for <br className="lg:block" /> Your
Development Teams
</SectionHeading>
<SectionHeading as="p" variant="subtitle" className="mt-6">
Get the tools and structure to tackle complex projects, streamline
workflows, and{' '}
<Strong>empower your engineers to do their best work</Strong>.
</SectionHeading>
</div>
</div>
);
}