c25c0f4698
Reworks the pricing surface in one PR: a new Enterprise tier on the
pricing page, five competitor pricing comparison pages, and the pricing
page section that links to them.
## Enterprise tier (pricing page)
- Third plan on both the cloud and self-hosting views: "from $50k /year"
with a "Talk to sales" CTA opening the existing contact modal.
- Cloud bullets: single-tenant isolation, IP allow-listing, SCIM
provisioning, dedicated support & SLA. Self-host: SCIM, air-gapped
deployment, LTS releases.
- Comparison table gains an Enterprise column (inherits Organization
values unless a row overrides) plus an Enterprise category of rows.
- New halftone building icon generated with the /halftone studio to
match the plan icon family.
- Pro and Organization pricing unchanged ($9/$19, in sync with Stripe).
## Competitor comparison pages
-
`/compare-pricing/{hubspot,salesforce,attio,pipedrive,microsoft-dynamics}`:
one shared template driven by a data file per vendor.
- Feature-by-feature cost table (competitor price + unlocking tier +
source link per claim, "checked on July 30, 2026" note, "spotted an
inaccuracy" link), a side-by-side bill for a 20-person team using the
PlanCard visual language with a savings badge cloned from the billing
toggle's -25% chip, and a one-line "fair play" note per vendor.
- Prices are 2026 list prices researched from vendors' public pricing
pages, billed annually. Routes registered in the website route registry
(indexed, sitemap, hreflang).
## Pricing page hub
- The salesfarce section intro becomes "Compare the real cost" with the
five comparison links using the footer's hover-marker link style. The
parody widget is unchanged.
Locale catalogs untouched for the i18n bot. Typecheck, lint, and the
website test suite pass.
Worth a second pair of eyes: the Pipedrive plan names/prices (2025
rebrand; their pricing page blocks fetchers) and the Salesforce "+30% of
spend" support/sandbox figures.
468 lines
12 KiB
TypeScript
468 lines
12 KiB
TypeScript
import { msg } from '@lingui/core/macro';
|
|
|
|
import { type PlanTableDataType } from './plan-table-types';
|
|
|
|
export const PLAN_TABLE_DATA: PlanTableDataType = {
|
|
featureColumnLabel: msg`Name`,
|
|
initialVisibleRowCount: 15,
|
|
rows: [
|
|
{
|
|
featureLabel: msg`Price`,
|
|
selfHostTiers: {
|
|
enterprise: { kind: 'text', text: msg`From $50k/year` },
|
|
organization: { kind: 'text', text: msg`$19` },
|
|
pro: { kind: 'text', text: msg`$0` },
|
|
},
|
|
tiers: {
|
|
enterprise: { kind: 'text', text: msg`From $50k/year` },
|
|
organization: { kind: 'text', text: msg`$19` },
|
|
pro: { kind: 'text', text: msg`$9` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Seats limit`,
|
|
tiers: {
|
|
organization: { kind: 'text', text: msg`Unlimited` },
|
|
pro: { kind: 'text', text: msg`Unlimited` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{ title: msg`Workspace`, type: 'category' },
|
|
{
|
|
featureLabel: msg`Custom objects`,
|
|
tiers: {
|
|
organization: { kind: 'text', text: msg`Unlimited` },
|
|
pro: { kind: 'text', text: msg`Unlimited` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Custom fields`,
|
|
tiers: {
|
|
organization: { kind: 'text', text: msg`Unlimited` },
|
|
pro: { kind: 'text', text: msg`Unlimited` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Custom views`,
|
|
tiers: {
|
|
organization: { kind: 'text', text: msg`Unlimited` },
|
|
pro: { kind: 'text', text: msg`Unlimited` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`View types`,
|
|
tiers: {
|
|
organization: { kind: 'text', text: msg`Table, Kanban, Calendar` },
|
|
pro: { kind: 'text', text: msg`Table, Kanban, Calendar` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Custom layout`,
|
|
tiers: {
|
|
organization: { kind: 'text', text: msg`Unlimited` },
|
|
pro: { kind: 'text', text: msg`Unlimited` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Records`,
|
|
tiers: {
|
|
organization: { kind: 'text', text: msg`Unlimited` },
|
|
pro: { kind: 'text', text: msg`Unlimited` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`CSV import & export`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'yes', label: msg`Yes` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Languages`,
|
|
tiers: {
|
|
organization: { kind: 'text', text: msg`30+` },
|
|
pro: { kind: 'text', text: msg`30+` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{ title: msg`Reports`, type: 'category' },
|
|
{
|
|
featureLabel: msg`Number of dashboards`,
|
|
tiers: {
|
|
organization: { kind: 'text', text: msg`Unlimited` },
|
|
pro: { kind: 'text', text: msg`Unlimited` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{ title: msg`Emails & Calendar`, type: 'category' },
|
|
{
|
|
featureLabel: msg`Internet accounts per user`,
|
|
tiers: {
|
|
organization: { kind: 'text', text: msg`Unlimited` },
|
|
pro: { kind: 'text', text: msg`Unlimited` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Folder/Label import`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'yes', label: msg`Yes` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Email sharing`,
|
|
tiers: {
|
|
organization: { kind: 'text', text: msg`Fully customizable` },
|
|
pro: { kind: 'text', text: msg`Fully customizable` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{ title: msg`AI & Automations`, type: 'category' },
|
|
{
|
|
featureLabel: msg`Workflows`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'yes', label: msg`Yes` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`AI agents`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'yes', label: msg`Yes` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
appliesTo: 'selfHost',
|
|
featureLabel: msg`Custom AI models`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'dash' },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{ title: msg`Security`, type: 'category' },
|
|
{
|
|
featureLabel: msg`Two-factor authentication`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'yes', label: msg`Yes` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`User roles`,
|
|
tiers: {
|
|
organization: { kind: 'text', text: msg`Unlimited` },
|
|
pro: { kind: 'text', text: msg`Unlimited` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Read/Edit/Delete permissions`,
|
|
tiers: {
|
|
organization: { kind: 'text', text: msg`Unlimited` },
|
|
pro: { kind: 'text', text: msg`Unlimited` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Field-level permissions`,
|
|
tiers: {
|
|
organization: { kind: 'text', text: msg`Unlimited` },
|
|
pro: { kind: 'text', text: msg`Unlimited` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Row-level permissions`,
|
|
tiers: {
|
|
organization: { kind: 'text', text: msg`Unlimited` },
|
|
pro: { kind: 'dash' },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`SSO`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'dash' },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Encryption key rotation`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'dash' },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Audit logs`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'dash' },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Environments`,
|
|
tiers: {
|
|
organization: { kind: 'text', text: msg`Local, Production` },
|
|
pro: { kind: 'text', text: msg`Local, Production` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Impersonate users`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'yes', label: msg`Yes` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{ title: msg`Support`, type: 'category' },
|
|
{
|
|
featureLabel: msg`Community`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'yes', label: msg`Yes` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Help center`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'yes', label: msg`Yes` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Email and Chat`,
|
|
selfHostTiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'dash' },
|
|
},
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'yes', label: msg`Yes` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Priority support`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'dash' },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Dedicated support & SLA`,
|
|
tiers: {
|
|
enterprise: { kind: 'yes', label: msg`Yes` },
|
|
organization: { kind: 'dash' },
|
|
pro: { kind: 'dash' },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Onboarding Packs`,
|
|
selfHostTiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'dash' },
|
|
},
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'yes', label: msg`Yes` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Implementation partners`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'dash' },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{ title: msg`Customization`, type: 'category' },
|
|
{
|
|
featureLabel: msg`Custom apps`,
|
|
tiers: {
|
|
organization: { kind: 'text', text: msg`Unlimited` },
|
|
pro: { kind: 'text', text: msg`Unlimited` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
appliesTo: 'cloud',
|
|
featureLabel: msg`Subdomain (yourco.twenty.com)`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'yes', label: msg`Yes` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
appliesTo: 'cloud',
|
|
featureLabel: msg`Custom domain (crm.yourco.com)`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'dash' },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{ title: msg`Developers`, type: 'category' },
|
|
{
|
|
featureLabel: msg`REST & GraphQL API`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'yes', label: msg`Yes` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Webhooks`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'yes', label: msg`Yes` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`MCP server`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'yes', label: msg`Yes` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Install shared tarball app`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'dash' },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
appliesTo: 'cloud',
|
|
featureLabel: msg`API calls`,
|
|
tiers: {
|
|
enterprise: { kind: 'text', text: msg`Custom` },
|
|
organization: { kind: 'text', text: msg`100 per minute` },
|
|
pro: { kind: 'text', text: msg`50 per minute` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{ appliesTo: 'selfHost', title: msg`Self-hosting`, type: 'category' },
|
|
{
|
|
appliesTo: 'selfHost',
|
|
featureLabel: msg`Source code access`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'yes', label: msg`Yes` },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
appliesTo: 'selfHost',
|
|
featureLabel: msg`Commercial license (no AGPL obligations)`,
|
|
tiers: {
|
|
organization: { kind: 'yes', label: msg`Yes` },
|
|
pro: { kind: 'dash' },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{ title: msg`Enterprise`, type: 'category' },
|
|
{
|
|
appliesTo: 'cloud',
|
|
featureLabel: msg`Single-tenant isolation`,
|
|
tiers: {
|
|
enterprise: { kind: 'yes', label: msg`Yes` },
|
|
organization: { kind: 'dash' },
|
|
pro: { kind: 'dash' },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
appliesTo: 'cloud',
|
|
featureLabel: msg`IP allow-listing`,
|
|
tiers: {
|
|
enterprise: { kind: 'yes', label: msg`Yes` },
|
|
organization: { kind: 'dash' },
|
|
pro: { kind: 'dash' },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`SCIM provisioning`,
|
|
tiers: {
|
|
enterprise: { kind: 'yes', label: msg`Yes` },
|
|
organization: { kind: 'dash' },
|
|
pro: { kind: 'dash' },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
appliesTo: 'selfHost',
|
|
featureLabel: msg`Air-gapped deployment`,
|
|
tiers: {
|
|
enterprise: { kind: 'yes', label: msg`Yes` },
|
|
organization: { kind: 'dash' },
|
|
pro: { kind: 'dash' },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
appliesTo: 'selfHost',
|
|
featureLabel: msg`LTS releases`,
|
|
tiers: {
|
|
enterprise: { kind: 'yes', label: msg`Yes` },
|
|
organization: { kind: 'dash' },
|
|
pro: { kind: 'dash' },
|
|
},
|
|
type: 'row',
|
|
},
|
|
{
|
|
featureLabel: msg`Security review & DPA`,
|
|
tiers: {
|
|
enterprise: { kind: 'yes', label: msg`Yes` },
|
|
organization: { kind: 'dash' },
|
|
pro: { kind: 'dash' },
|
|
},
|
|
type: 'row',
|
|
},
|
|
],
|
|
seeMoreFeaturesCta: {
|
|
collapseLabel: msg`Show less`,
|
|
expandLabel: msg`See more features`,
|
|
},
|
|
tierColumns: [
|
|
{ id: 'pro', label: { cloud: msg`Pro`, selfHost: msg`Pro` } },
|
|
{
|
|
id: 'organization',
|
|
label: { cloud: msg`Organization`, selfHost: msg`Organization` },
|
|
},
|
|
{
|
|
id: 'enterprise',
|
|
label: { cloud: msg`Enterprise`, selfHost: msg`Enterprise` },
|
|
},
|
|
],
|
|
};
|