From 8ab0c242cdc539726c76d039010169e773647a36 Mon Sep 17 00:00:00 2001 From: bcotrim Date: Mon, 31 Aug 2026 11:19:37 +0100 Subject: [PATCH 1/2] Strip local domain suffix from publish flow domain suggestion --- apps/studio/src/lib/generate-checkout-url.ts | 4 +-- .../core/connectors/publish-checkout-url.ts | 6 ++++- packages/common/lib/domains.ts | 10 +++++++ packages/common/lib/tests/domains.test.ts | 26 +++++++++++++++++++ 4 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 packages/common/lib/tests/domains.test.ts diff --git a/apps/studio/src/lib/generate-checkout-url.ts b/apps/studio/src/lib/generate-checkout-url.ts index b5e455fd75..d6288b7fd3 100644 --- a/apps/studio/src/lib/generate-checkout-url.ts +++ b/apps/studio/src/lib/generate-checkout-url.ts @@ -1,4 +1,4 @@ -import { DEFAULT_CUSTOM_DOMAIN_SUFFIX } from '@studio/common/constants'; +import { stripLocalDomainSuffix } from '@studio/common/lib/domains'; export function generateCheckoutUrl( selectedSite?: SiteDetails, @@ -15,7 +15,7 @@ export function generateCheckoutUrl( } const suggestedName = selectedSite.customDomain - ? selectedSite.customDomain.replace( DEFAULT_CUSTOM_DOMAIN_SUFFIX, '' ) + ? stripLocalDomainSuffix( selectedSite.customDomain ) : selectedSite.name; url.searchParams.set( 'studioSiteId', String( selectedSite.id ) ); diff --git a/apps/ui/src/data/core/connectors/publish-checkout-url.ts b/apps/ui/src/data/core/connectors/publish-checkout-url.ts index c91193396d..2acb735db2 100644 --- a/apps/ui/src/data/core/connectors/publish-checkout-url.ts +++ b/apps/ui/src/data/core/connectors/publish-checkout-url.ts @@ -1,3 +1,4 @@ +import { stripLocalDomainSuffix } from '@studio/common/lib/domains'; import type { SiteDetails } from '../types'; export function buildPublishCheckoutUrl( site: SiteDetails ): string { @@ -6,7 +7,10 @@ export function buildPublishCheckoutUrl( site: SiteDetails ): string { url.searchParams.set( 'section', 'publish-site' ); url.searchParams.set( 'showDomainStep', 'true' ); url.searchParams.set( 'studioSiteId', site.id ); - url.searchParams.set( 'new', site.customDomain ?? site.name ); + url.searchParams.set( + 'new', + site.customDomain ? stripLocalDomainSuffix( site.customDomain ) : site.name + ); url.searchParams.set( 'autoOpenPush', 'true' ); return url.toString(); } diff --git a/packages/common/lib/domains.ts b/packages/common/lib/domains.ts index 4f7b0ef85e..9b72c25a53 100644 --- a/packages/common/lib/domains.ts +++ b/packages/common/lib/domains.ts @@ -14,6 +14,16 @@ export const generateCustomDomainFromSiteName = ( siteName: string ): string => return `${ domainBase }${ DEFAULT_CUSTOM_DOMAIN_SUFFIX }`; }; +export const stripLocalDomainSuffix = ( domain: string ): string => { + if ( domain.endsWith( DEFAULT_CUSTOM_DOMAIN_SUFFIX ) ) { + return domain.slice( 0, -DEFAULT_CUSTOM_DOMAIN_SUFFIX.length ); + } + if ( domain.endsWith( '.local' ) ) { + return domain.slice( 0, -'.local'.length ); + } + return domain; +}; + export const getDomainNameValidationError = ( useCustomDomain: boolean, domainName: string | null, diff --git a/packages/common/lib/tests/domains.test.ts b/packages/common/lib/tests/domains.test.ts new file mode 100644 index 0000000000..db62efc9b4 --- /dev/null +++ b/packages/common/lib/tests/domains.test.ts @@ -0,0 +1,26 @@ +/** + * @vitest-environment node + */ +import { stripLocalDomainSuffix } from '@studio/common/lib/domains'; + +describe( 'stripLocalDomainSuffix', () => { + it( 'strips the default .wp.local suffix entirely', () => { + expect( stripLocalDomainSuffix( 'mysite.wp.local' ) ).toBe( 'mysite' ); + } ); + + it( 'strips a single trailing .local label', () => { + expect( stripLocalDomainSuffix( 'mysite.local' ) ).toBe( 'mysite' ); + } ); + + it( 'keeps inner labels when stripping .local', () => { + expect( stripLocalDomainSuffix( 'mysite.com.local' ) ).toBe( 'mysite.com' ); + } ); + + it( 'only strips the suffix, not inner occurrences', () => { + expect( stripLocalDomainSuffix( 'wp.local.mysite.local' ) ).toBe( 'wp.local.mysite' ); + } ); + + it( 'leaves non-local domains unchanged', () => { + expect( stripLocalDomainSuffix( 'mysite.com' ) ).toBe( 'mysite.com' ); + } ); +} ); From 37a6d460c80bd05e9568e7e584097dd15451cfb2 Mon Sep 17 00:00:00 2001 From: bcotrim Date: Thu, 3 Sep 2026 13:20:25 +0100 Subject: [PATCH 2/2] Extract .local suffix into LOCAL_DOMAIN_SUFFIX constant --- packages/common/constants.ts | 1 + packages/common/lib/domains.ts | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/common/constants.ts b/packages/common/constants.ts index 990163a484..ebdea070ea 100644 --- a/packages/common/constants.ts +++ b/packages/common/constants.ts @@ -35,6 +35,7 @@ export const CERT_UNTRUSTED_ROOT = 'CERT_TRUST_IS_UNTRUSTED_ROOT'; // Windows AP // Custom domains export const DEFAULT_CUSTOM_DOMAIN_SUFFIX = '.wp.local'; +export const LOCAL_DOMAIN_SUFFIX = '.local'; // WordPress constants export const MINIMUM_WORDPRESS_VERSION = '6.2.1' as const; // https://wordpress.github.io/wordpress-playground/blueprints/examples/#load-an-older-wordpress-version diff --git a/packages/common/lib/domains.ts b/packages/common/lib/domains.ts index 9b72c25a53..416bc8f50a 100644 --- a/packages/common/lib/domains.ts +++ b/packages/common/lib/domains.ts @@ -1,5 +1,5 @@ import { __ } from '@wordpress/i18n'; -import { DEFAULT_CUSTOM_DOMAIN_SUFFIX } from '@studio/common/constants'; +import { DEFAULT_CUSTOM_DOMAIN_SUFFIX, LOCAL_DOMAIN_SUFFIX } from '@studio/common/constants'; import { sanitizeFolderName } from './sanitize-folder-name'; const DOMAIN_PATTERN = @@ -18,8 +18,8 @@ export const stripLocalDomainSuffix = ( domain: string ): string => { if ( domain.endsWith( DEFAULT_CUSTOM_DOMAIN_SUFFIX ) ) { return domain.slice( 0, -DEFAULT_CUSTOM_DOMAIN_SUFFIX.length ); } - if ( domain.endsWith( '.local' ) ) { - return domain.slice( 0, -'.local'.length ); + if ( domain.endsWith( LOCAL_DOMAIN_SUFFIX ) ) { + return domain.slice( 0, -LOCAL_DOMAIN_SUFFIX.length ); } return domain; }; @@ -49,7 +49,7 @@ export const getDomainNameValidationError = ( return __( 'The domain name is too long' ); } - if ( ! domainName.endsWith( '.local' ) ) { + if ( ! domainName.endsWith( LOCAL_DOMAIN_SUFFIX ) ) { return __( 'The domain name must end with .local' ); }