Repository: Automattic/wp-calypso
Pull request #103344: Hosting Dashboard V2: Add new site dropdown
Author: login: youknowriad
Created: 2025-05-12T12:37:50Z | Merged: 2025-05-16T10:37:51Z

DOTCOM-12982

## Proposed Changes

This PR makes the "Add new site" button work in the hosting dashboard v2. While right now it duplicates the code base of the existing component and adapts it to the guidelines of the v2 dashboard, the ultimate goal (either in this PR or a follow-up is to reuse this new rewritten component in the v1 dashboard too, that way we evolve it in a unique place).

We need to address a few questions before able to merge this, check inline comments.

## Testing Instructions

 - Open the v2 dashboard /v2
 - Click "Add new site"
 - Ensure the different options work as intended


Diff:
diff --git a/client/dashboard/.eslintrc.js b/client/dashboard/.eslintrc.js
index b6af564ff341..d89a9eabe0c9 100644
--- a/client/dashboard/.eslintrc.js
+++ b/client/dashboard/.eslintrc.js
@@ -11,12 +11,12 @@ module.exports = {
 							'!calypso/lib',
 							'calypso/lib/*',
 							'!calypso/lib/wp',
-							'!calypso/components',
-							'calypso/components/*',
 							// Allowed: calypso/assets/icons
+							// Allowed: calypso/assets/images
 							'!calypso/assets',
 							'calypso/assets/*',
 							'!calypso/assets/icons',
+							'!calypso/assets/images',
 							// Please do not add exceptions unless agreed on
 							// with the #architecture group.
 						],
@@ -34,7 +34,9 @@ module.exports = {
 							'!@automattic/components/src/core-badge',
 							'!@automattic/components/src/breadcrumbs',
 							'!@automattic/components/src/breadcrumbs/types',
+							'!@automattic/calypso-analytics',
 							'!@automattic/dataviews',
+							'!@automattic/number-formatters',
 							// Please do not add exceptions unless agreed on
 							// with the #architecture group.
 						],
diff --git a/client/dashboard/sites/add-new-site/column.tsx b/client/dashboard/sites/add-new-site/column.tsx
new file mode 100644
index 000000000000..251938a57fa0
--- /dev/null
+++ b/client/dashboard/sites/add-new-site/column.tsx
@@ -0,0 +1,16 @@
+import { __experimentalVStack as VStack, __experimentalText as Text } from '@wordpress/components';
+
+function Column( { title, children }: { title?: string; children: React.ReactNode } ) {
+	return (
+		<VStack spacing={ 4 } style={ { width: '260px' } }>
+			{ title && (
+				<Text variant="muted" size="subheadline" upperCase weight={ 500 }>
+					{ title }
+				</Text>
+			) }
+			{ children }
+		</VStack>
+	);
+}
+
+export default Column;
diff --git a/client/dashboard/sites/add-new-site/index.tsx b/client/dashboard/sites/add-new-site/index.tsx
new file mode 100644
index 000000000000..f98f1517f85c
--- /dev/null
+++ b/client/dashboard/sites/add-new-site/index.tsx
@@ -0,0 +1,127 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { useViewportMatch } from '@wordpress/compose';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
+	const isDesktop = useViewportMatch( 'medium' );
+	const Wrapper = isDesktop ? HStack : VStack;
+	const offer = sprintf(
+		// translators: %s is a percentage like 55% off
+		__( 'Get a free domain and up to %s off' ),
+		formatNumber( 0.55, {
+			numberFormatOptions: { style: 'percent' },
+		} )
+	);
+
+	return (
+		<Wrapper alignment="flex-start" style={ { padding: '16px' } } spacing={ 6 }>
+			<Column title={ __( 'Add new site' ) }>
+				<MenuItem
+					icon={ <WordPressLogo /> }
+					title="WordPress.com"
+					description={ __( 'Build and grow your site, all in one powerful platform.' ) }
+					onClick={ wordpressClick }
+					href="/start?source=sites-dashboard&ref=new-site-popover"
+				/>
+				<MenuItem
+					icon={ <JetpackLogo /> }
+					title={ __( 'Via the Jetpack plugin' ) }
+					description={ __( 'Install the Jetpack plugin on an existing site.' ) }
+					onClick={ jetpackClick }
+					href={ `/jetpack/connect?cta_from=${ TRACK_SOURCE_NAME }&cta_id=add-site` }
+				/>
+			</Column>
+			<Column title={ __( 'Migrate and import' ) }>
+				<MenuItem
+					icon={ reusableBlock }
+					title={ __( 'Migrate' ) }
+					description={ __( 'Bring your entire WordPress site to WordPress.com.' ) }
+					onClick={ migrateClick }
+					href="/setup/site-migration?source=sites-dashboard&ref=new-site-popover&action=migrate"
+				/>
+				<MenuItem
+					icon={ <Icon icon={ download } size={ 18 } /> }
+					title={ __( 'Import' ) }
+					description={ __( 'Use a backup to only import content from other platforms.' ) }
+					onClick={ importClick }
+					href="/setup/site-migration/create-site?source=sites-dashboard&ref=new-site-popover&action=import"
+				/>
+			</Column>
+
+			<Button
+				href="https://wordpress.com/setup/onboarding"
+				onClick={ offerClick }
+				style={ {
+					display: 'block',
+					height: 'auto',
+					textAlign: 'left',
+					width: '260px',
+					padding: 0,
+				} }
+			>
+				<VStack className="dashboard-add-new-site__banner">
+					<img src={ devSiteBanner } alt={ offer } />
+					<Text size="title">{ offer }</Text>
+					<Text variant="muted" as="p">
+						{ sprintf(
+							// translators: %s is a percentage like 55% off
+							__(
+								'Save up to %s on annual plans and get a free custom domain for a year. Your next site is just a step away.'
+							),
+							formatNumber( 0.55, {
+								numberFormatOptions: { style: 'percent' },
+							} )
+						) }
+					</Text>
+					<div>{ __( 'Unlock offer' ) }</div>
+				</VStack>
+			</Button>
+		</Wrapper>
+	);
+}
+
+export default AddNewSite;
diff --git a/client/dashboard/sites/add-new-site/menu-item.tsx b/client/dashboard/sites/add-new-site/menu-item.tsx
new file mode 100644
index 000000000000..a8ea1be62a55
--- /dev/null
+++ b/client/dashboard/sites/add-new-site/menu-item.tsx
@@ -0,0 +1,47 @@
+import {
+	__experimentalVStack as VStack,
+	__experimentalHStack as HStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { Icon } from '@wordpress/icons';
+import React from 'react';
+
+type Props = {
+	children?: JSX.Element;
+	description: string;
+	title: string;
+	icon: JSX.Element;
+};
+
+function MenuItem( {
+	children,
+	description,
+	title,
+	icon,
+	...buttonProps
+}: Props & React.ComponentProps< typeof Button > ) {
+	return (
+		<Button
+			className="dashboard-add-new-site__menu-item"
+			{ ...buttonProps }
+			label={ title }
+			showTooltip={ false }
+		>
+			<HStack alignment="start" spacing={ 2 }>
+				<div style={ { flexShrink: 0 } }>
+					<Icon className="dashboard-add-new-site__menu-item-icon" icon={ icon } />
+				</div>
+				<VStack>
+					<Text>{ title }</Text>
+					<Text variant="muted" as="p">
+						{ description }
+					</Text>
+					{ children }
+				</VStack>
+			</HStack>
+		</Button>
+	);
+}
+
+export default MenuItem;
diff --git a/client/dashboard/sites/add-new-site/style.scss b/client/dashboard/sites/add-new-site/style.scss
new file mode 100644
index 000000000000..a891e7222526
--- /dev/null
+++ b/client/dashboard/sites/add-new-site/style.scss
@@ -0,0 +1,32 @@
+@import '@wordpress/base-styles/breakpoints';
+@import '@wordpress/base-styles/mixins';
+@import '@wordpress/base-styles/variables';
+@import '@wordpress/base-styles/colors';
+
+.dashboard-add-new-site__menu-item {
+	height: auto;
+	text-align: left;;
+	padding: 8px;
+
+	&:hover {
+		color: inherit !important; // avoid changing the color on hover
+		background: $gray-100;
+		border-radius: $radius-medium;
+	}
+}
+
+.dashboard-add-new-site__menu-item-icon {
+	width: 24px;
+	height: auto;
+	display: none;
+
+	@include break-medium {
+		display: block;
+	}
+}
+
+.dashboard-add-new-site__banner {
+	background: $gray-100;
+	border-radius: $radius-medium;
+	padding: $grid-unit-20;
+}
diff --git a/client/dashboard/sites/index.tsx b/client/dashboard/sites/index.tsx
index 77ddac912900..3e99f2add20f 100644
--- a/client/dashboard/sites/index.tsx
+++ b/client/dashboard/sites/index.tsx
@@ -1,7 +1,7 @@
 import { DataViews, filterSortAndPaginate } from '@automattic/dataviews';
 import { useQuery } from '@tanstack/react-query';
 import { useNavigate } from '@tanstack/react-router';
-import { Button, ExternalLink } from '@wordpress/components';
+import { Button, ExternalLink, Dropdown } from '@wordpress/components';
 import { useResizeObserver } from '@wordpress/compose';
 import { __ } from '@wordpress/i18n';
 import { Icon, check } from '@wordpress/icons';
@@ -12,6 +12,7 @@ import DataViewsCard from '../components/dataviews-card';
 import { PageHeader } from '../components/page-header';
 import PageLayout from '../components/page-layout';
 import { STATUS_LABELS, getSiteStatus, getSiteStatusLabel } from '../utils/site-status';
+import AddNewSite from './add-new-site';
 import SiteIcon from './site-icon';
 import SitePreview from './site-preview';
 import type { Site } from '../data/types';
@@ -224,9 +225,21 @@ export default function Sites() {
 				<PageHeader
 					title={ __( 'Sites' ) }
 					actions={
-						<Button variant="primary" __next40pxDefaultSize>
-							{ __( 'Add New Site' ) }
-						</Button>
+						<Dropdown
+							popoverProps={ { placement: 'bottom-end', offset: 10, noArrow: false } }
+							focusOnMount
+							renderToggle={ ( { isOpen, onToggle } ) => (
+								<Button
+									variant="primary"
+									onClick={ onToggle }
+									__next40pxDefaultSize
+									aria-expanded={ isOpen }
+								>
+									{ __( 'Add New Site' ) }
+								</Button>
+							) }
+							renderContent={ () => <AddNewSite /> }
+						/>
 					}
 				/>
 				<DataViewsCard>


Reviews:
user: login: youknowriad
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T12:38:48Z
user: login: youknowriad
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T12:39:36Z
user: login: youknowriad
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T12:40:06Z
user: login: youknowriad
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T12:41:25Z
user: login: youknowriad
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T12:42:38Z
user: login: StevenDufresne
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T21:33:54Z
user: login: StevenDufresne
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T21:42:55Z
user: login: StevenDufresne
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T22:09:58Z
user: login: StevenDufresne
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T22:10:48Z
user: login: tyxla
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-13T13:55:46Z
user: login: tellthemachines
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T03:54:52Z
user: login: tellthemachines
body: Thanks for the PR! I gave this a quick test run and it's not looking too good on mobile:

<img width="412" alt="Screenshot 2025-05-14 at 3 12 11 pm" src="https://github.com/user-attachments/assets/b2978da3-5a95-42ee-9a67-058e45522dc4" />

The component used in the current dashboard adjusts its flex-direction depending on screen size:

<img width="332" alt="Screenshot 2025-05-14 at 3 11 55 pm" src="https://github.com/user-attachments/assets/19ff3ffe-cd58-4fc8-8c4c-74484646ad7b" />

We could emulate the current behaviour by styling the Column wrapper with CSS instead of using a `HStack`. Or I guess we could leverage the `direction` property of `HStack` to render it as row or column conditional on screen size, but that would require checking the viewport size with JS which feels unnecessary if we can do it with CSS instead 😄  

state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T05:32:13Z
user: login: youknowriad
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T09:05:21Z
user: login: tyxla
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T14:41:48Z
user: login: tyxla
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T14:45:37Z
user: login: youknowriad
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T15:14:37Z
user: login: tyxla
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T15:17:22Z
user: login: youknowriad
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T15:23:24Z
user: login: tyxla
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T16:08:41Z
user: login: youknowriad
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T16:44:11Z
user: login: jsnajdr
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-15T09:37:07Z
user: login: jsnajdr
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-15T09:44:23Z
user: login: youknowriad
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T09:46:04Z
user: login: jsnajdr
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-15T09:59:04Z
user: login: youknowriad
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T10:01:20Z
user: login: jsnajdr
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-15T10:06:29Z
user: login: youknowriad
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T10:16:05Z
user: login: tyxla
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-15T11:01:55Z
user: login: tyxla
body: This LGTM 👍 🚀 

Let's make sure to follow up on unifying the `AddNewSite` components
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-15T13:00:00Z

Review comments:
diff_hunk: @@ -11,12 +11,16 @@ module.exports = {
 							'!calypso/lib',
 							'calypso/lib/*',
 							'!calypso/lib/wp',
-							'!calypso/components',
-							'calypso/components/*',
+							// Allowed: calypso/lib/formatting/prevent-widows
+							'!calypso/lib/formatting',
+							'calypso/lib/formatting/*',
+							'!calypso/lib/formatting/prevent-widows',
path: client/dashboard/.eslintrc.js
user: login: youknowriad
body: This file seems safe enough to use in the dashboard. I wonder why it's not a "string" package or something like that.
created_at: 2025-05-12T12:38:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -32,7 +36,9 @@ module.exports = {
 							'@automattic/components/src/*',
 							'!@automattic/components/src/summary-button',
 							'!@automattic/components/src/core-badge',
+							'!@automattic/calypso-analytics',
 							'!@automattic/dataviews',
+							'!@automattic/number-formatters',
path: client/dashboard/.eslintrc.js
user: login: youknowriad
body: Both of these two packages seems like they are "well maintained" and "safe to use" package without extra bloat... But I would love to have your thoughts @tyxla @jsnajdr 
created_at: 2025-05-12T12:39:36Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,139 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import clsx from 'clsx';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import { preventWidows } from 'calypso/lib/formatting';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
path: client/dashboard/sites/add-new-site/index.tsx
user: login: youknowriad
body: I have reused the same events that are being currently used.
created_at: 2025-05-12T12:40:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,139 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import clsx from 'clsx';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import { preventWidows } from 'calypso/lib/formatting';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
+	return (
+		<HStack alignment="flex-start" style={ { padding: '16px' } } spacing={ 4 }>
+			<Column title={ __( 'Add new site' ) }>
+				<MenuItem
+					icon={ <WordPressLogo /> }
+					title={ __( 'WordPress.com' ) }
+					description={ preventWidows(
+						__( 'Build and grow your site, all in one powerful platform.' )
+					) }
+					onClick={ wordpressClick }
+					href="/start?source=sites-dashboard&ref=new-site-popover"
+				/>
+				<MenuItem
+					icon={ <JetpackLogo /> }
+					title={ __( 'Via the Jetpack plugin' ) }
+					description={ preventWidows( __( 'Install the Jetpack plugin on an existing site.' ) ) }
+					onClick={ jetpackClick }
+					href={ `/jetpack/connect?cta_from=${ TRACK_SOURCE_NAME }&cta_id=add-site` }
+				/>
+			</Column>
+			<Column title={ __( 'Migrate and import' ) }>
+				<MenuItem
+					icon={ reusableBlock }
+					title={ __( 'Migrate' ) }
+					description={ preventWidows(
+						__( 'Bring your entire WordPress site to WordPress.com.' )
+					) }
+					onClick={ migrateClick }
+					href="/setup/site-migration?source=sites-dashboard&ref=new-site-popover&action=migrate"
+				/>
+				<MenuItem
+					icon={ <Icon icon={ download } size={ 18 } /> }
+					title={ __( 'Import' ) }
+					description={ preventWidows(
+						__( 'Use a backup to only import content from other platforms.' )
+					) }
+					onClick={ importClick }
+					href="/setup/site-migration/create-site?source=sites-dashboard&ref=new-site-popover&action=import"
+				/>
+			</Column>
+
+			<Button
+				// Figure out localizeUrl
+				href="https://wordpress.com/setup/onboarding"
path: client/dashboard/sites/add-new-site/index.tsx
user: login: youknowriad
body: localizeUrl is defined in `i18n-utils` package. I don't really like "utils" packages but maybe that one would be ok to use. What do you think @jsnajdr ? What would be your recommendation.
created_at: 2025-05-12T12:41:25Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,139 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import clsx from 'clsx';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import { preventWidows } from 'calypso/lib/formatting';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
+	return (
+		<HStack alignment="flex-start" style={ { padding: '16px' } } spacing={ 4 }>
+			<Column title={ __( 'Add new site' ) }>
+				<MenuItem
+					icon={ <WordPressLogo /> }
+					title={ __( 'WordPress.com' ) }
+					description={ preventWidows(
+						__( 'Build and grow your site, all in one powerful platform.' )
+					) }
+					onClick={ wordpressClick }
+					href="/start?source=sites-dashboard&ref=new-site-popover"
path: client/dashboard/sites/add-new-site/index.tsx
user: login: youknowriad
body: Since we're using regular links now for all these links instead of `page` I'm wondering if:

 - Should we be using "page" for the links that go outside the dashboard v2 (I don't really want to import page tbh)
 - Should we call "localizeUrl" on these links?

cc @jsnajdr 
created_at: 2025-05-12T12:42:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,134 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import { preventWidows } from 'calypso/lib/formatting';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
+	return (
+		<HStack alignment="flex-start" style={ { padding: '16px' } } spacing={ 4 }>
+			<Column title={ __( 'Add new site' ) }>
+				<MenuItem
+					icon={ <WordPressLogo /> }
+					title={ __( 'WordPress.com' ) }
+					description={ preventWidows(
path: client/dashboard/sites/add-new-site/index.tsx
user: login: StevenDufresne
body: I forget where it was mentioned, but it was suggested that CSS would be a better approach to prevent widows moving forward.
created_at: 2025-05-12T21:33:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,134 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import { preventWidows } from 'calypso/lib/formatting';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
+	return (
+		<HStack alignment="flex-start" style={ { padding: '16px' } } spacing={ 4 }>
+			<Column title={ __( 'Add new site' ) }>
+				<MenuItem
+					icon={ <WordPressLogo /> }
+					title={ __( 'WordPress.com' ) }
+					description={ preventWidows(
+						__( 'Build and grow your site, all in one powerful platform.' )
+					) }
+					onClick={ wordpressClick }
+					href="/start?source=sites-dashboard&ref=new-site-popover"
+				/>
+				<MenuItem
+					icon={ <JetpackLogo /> }
+					title={ __( 'Via the Jetpack plugin' ) }
+					description={ preventWidows( __( 'Install the Jetpack plugin on an existing site.' ) ) }
+					onClick={ jetpackClick }
+					href={ `/jetpack/connect?cta_from=${ TRACK_SOURCE_NAME }&cta_id=add-site` }
+				/>
+			</Column>
+			<Column title={ __( 'Migrate and import' ) }>
path: client/dashboard/sites/add-new-site/index.tsx
user: login: StevenDufresne
body: These headings likely don't match the style guide. Can we update?

| This PR | Existing Sites dashboard |
|--------|--------|
| <img width="862" alt="Screenshot 2025-05-13 at 6 40 36 AM" src="https://github.com/user-attachments/assets/2737a7b5-b601-4ee4-87e6-9429fce3f377" /> | <img width="837" alt="Screenshot 2025-05-13 at 6 42 04 AM" src="https://github.com/user-attachments/assets/4cb95b02-3179-48b1-b978-092f7badcdfa" /> | 






created_at: 2025-05-12T21:42:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,134 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import { preventWidows } from 'calypso/lib/formatting';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
+	return (
+		<HStack alignment="flex-start" style={ { padding: '16px' } } spacing={ 4 }>
+			<Column title={ __( 'Add new site' ) }>
+				<MenuItem
+					icon={ <WordPressLogo /> }
+					title={ __( 'WordPress.com' ) }
+					description={ preventWidows(
+						__( 'Build and grow your site, all in one powerful platform.' )
+					) }
+					onClick={ wordpressClick }
+					href="/start?source=sites-dashboard&ref=new-site-popover"
+				/>
+				<MenuItem
+					icon={ <JetpackLogo /> }
+					title={ __( 'Via the Jetpack plugin' ) }
+					description={ preventWidows( __( 'Install the Jetpack plugin on an existing site.' ) ) }
+					onClick={ jetpackClick }
+					href={ `/jetpack/connect?cta_from=${ TRACK_SOURCE_NAME }&cta_id=add-site` }
+				/>
+			</Column>
+			<Column title={ __( 'Migrate and import' ) }>
path: client/dashboard/sites/add-new-site/index.tsx
user: login: StevenDufresne
body: (maybe default styling comes around to style this later. idk).
created_at: 2025-05-12T22:09:58Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,134 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import { preventWidows } from 'calypso/lib/formatting';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
+	return (
+		<HStack alignment="flex-start" style={ { padding: '16px' } } spacing={ 4 }>
+			<Column title={ __( 'Add new site' ) }>
+				<MenuItem
+					icon={ <WordPressLogo /> }
+					title={ __( 'WordPress.com' ) }
+					description={ preventWidows(
path: client/dashboard/sites/add-new-site/index.tsx
user: login: StevenDufresne
body: It's fine if we don't update here, but I imagine it'll stay like this forever :)
created_at: 2025-05-12T22:10:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,134 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import { preventWidows } from 'calypso/lib/formatting';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
+	return (
+		<HStack alignment="flex-start" style={ { padding: '16px' } } spacing={ 4 }>
+			<Column title={ __( 'Add new site' ) }>
+				<MenuItem
+					icon={ <WordPressLogo /> }
+					title={ __( 'WordPress.com' ) }
path: client/dashboard/sites/add-new-site/index.tsx
user: login: tyxla
body: We don't localize brand names do we? Seems like an unnecessary string to localize.
created_at: 2025-05-13T13:50:49Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,139 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import clsx from 'clsx';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import { preventWidows } from 'calypso/lib/formatting';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
+	return (
+		<HStack alignment="flex-start" style={ { padding: '16px' } } spacing={ 4 }>
+			<Column title={ __( 'Add new site' ) }>
+				<MenuItem
+					icon={ <WordPressLogo /> }
+					title={ __( 'WordPress.com' ) }
+					description={ preventWidows(
+						__( 'Build and grow your site, all in one powerful platform.' )
+					) }
+					onClick={ wordpressClick }
+					href="/start?source=sites-dashboard&ref=new-site-popover"
path: client/dashboard/sites/add-new-site/index.tsx
user: login: tyxla
body: What's a good reason to use `page`? What we have here seems like a good compromise.

And I think we generally localize these URLs, but at the same time, I believe `localizeUrl` requires a full URL and won't work with a relative path.
created_at: 2025-05-13T13:53:18Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,134 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import { preventWidows } from 'calypso/lib/formatting';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
+	return (
+		<HStack alignment="flex-start" style={ { padding: '16px' } } spacing={ 4 }>
+			<Column title={ __( 'Add new site' ) }>
+				<MenuItem
+					icon={ <WordPressLogo /> }
+					title={ __( 'WordPress.com' ) }
+					description={ preventWidows(
+						__( 'Build and grow your site, all in one powerful platform.' )
+					) }
+					onClick={ wordpressClick }
+					href="/start?source=sites-dashboard&ref=new-site-popover"
+				/>
+				<MenuItem
+					icon={ <JetpackLogo /> }
+					title={ __( 'Via the Jetpack plugin' ) }
+					description={ preventWidows( __( 'Install the Jetpack plugin on an existing site.' ) ) }
+					onClick={ jetpackClick }
+					href={ `/jetpack/connect?cta_from=${ TRACK_SOURCE_NAME }&cta_id=add-site` }
+				/>
+			</Column>
+			<Column title={ __( 'Migrate and import' ) }>
+				<MenuItem
+					icon={ reusableBlock }
+					title={ __( 'Migrate' ) }
+					description={ preventWidows(
+						__( 'Bring your entire WordPress site to WordPress.com.' )
+					) }
+					onClick={ migrateClick }
+					href="/setup/site-migration?source=sites-dashboard&ref=new-site-popover&action=migrate"
+				/>
+				<MenuItem
+					icon={ <Icon icon={ download } size={ 18 } /> }
+					title={ __( 'Import' ) }
+					description={ preventWidows(
+						__( 'Use a backup to only import content from other platforms.' )
+					) }
+					onClick={ importClick }
+					href="/setup/site-migration/create-site?source=sites-dashboard&ref=new-site-popover&action=import"
+				/>
+			</Column>
+
+			<Button
+				// Figure out localizeUrl
+				href="https://wordpress.com/setup/onboarding"
+				onClick={ offerClick }
+				style={ {
+					display: 'block',
+					height: 'auto',
+					textAlign: 'left',
+					width: '260px',
+					padding: 0,
+				} }
+			>
+				<VStack className="dashboard-add-new-site__banner">
+					<img src={ devSiteBanner } alt="Get a free domain and up to 55% off" />
path: client/dashboard/sites/add-new-site/index.tsx
user: login: tyxla
body: Let's be sure to localize all strings propery.
created_at: 2025-05-13T13:53:50Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,134 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import { preventWidows } from 'calypso/lib/formatting';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
+	return (
+		<HStack alignment="flex-start" style={ { padding: '16px' } } spacing={ 4 }>
+			<Column title={ __( 'Add new site' ) }>
+				<MenuItem
+					icon={ <WordPressLogo /> }
+					title={ __( 'WordPress.com' ) }
+					description={ preventWidows(
+						__( 'Build and grow your site, all in one powerful platform.' )
+					) }
+					onClick={ wordpressClick }
+					href="/start?source=sites-dashboard&ref=new-site-popover"
+				/>
+				<MenuItem
+					icon={ <JetpackLogo /> }
+					title={ __( 'Via the Jetpack plugin' ) }
+					description={ preventWidows( __( 'Install the Jetpack plugin on an existing site.' ) ) }
+					onClick={ jetpackClick }
+					href={ `/jetpack/connect?cta_from=${ TRACK_SOURCE_NAME }&cta_id=add-site` }
+				/>
+			</Column>
+			<Column title={ __( 'Migrate and import' ) }>
+				<MenuItem
+					icon={ reusableBlock }
+					title={ __( 'Migrate' ) }
+					description={ preventWidows(
+						__( 'Bring your entire WordPress site to WordPress.com.' )
+					) }
+					onClick={ migrateClick }
+					href="/setup/site-migration?source=sites-dashboard&ref=new-site-popover&action=migrate"
+				/>
+				<MenuItem
+					icon={ <Icon icon={ download } size={ 18 } /> }
+					title={ __( 'Import' ) }
+					description={ preventWidows(
+						__( 'Use a backup to only import content from other platforms.' )
+					) }
+					onClick={ importClick }
+					href="/setup/site-migration/create-site?source=sites-dashboard&ref=new-site-popover&action=import"
+				/>
+			</Column>
+
+			<Button
+				// Figure out localizeUrl
+				href="https://wordpress.com/setup/onboarding"
+				onClick={ offerClick }
+				style={ {
+					display: 'block',
+					height: 'auto',
+					textAlign: 'left',
+					width: '260px',
+					padding: 0,
+				} }
+			>
+				<VStack className="dashboard-add-new-site__banner">
+					<img src={ devSiteBanner } alt="Get a free domain and up to 55% off" />
+					<Text size="title">
+						{ sprintf(
+							// translators: %s is a percentage like 55% off
+							__( 'Get a free domain and up to %s off' ),
path: client/dashboard/sites/add-new-site/index.tsx
user: login: tyxla
body: Looks like this string should be used in the `alt` above as well. 
created_at: 2025-05-13T13:54:09Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,134 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import { preventWidows } from 'calypso/lib/formatting';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
+	return (
+		<HStack alignment="flex-start" style={ { padding: '16px' } } spacing={ 4 }>
+			<Column title={ __( 'Add new site' ) }>
+				<MenuItem
+					icon={ <WordPressLogo /> }
+					title={ __( 'WordPress.com' ) }
+					description={ preventWidows(
path: client/dashboard/sites/add-new-site/index.tsx
user: login: tyxla
body: @tellthemachines has been doing a bunch of that work in #103187, see #100475
created_at: 2025-05-13T13:55:29Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,40 @@
+import {
+	__experimentalVStack as VStack,
+	__experimentalHStack as HStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { Icon } from '@wordpress/icons';
+import React from 'react';
+
+type Props = {
+	children?: JSX.Element;
+	description: string;
+	title: string;
+	icon: JSX.Element;
+};
+
+function MenuItem( {
+	children,
+	description,
+	title,
+	icon,
+	...buttonProps
+}: Props & React.ComponentProps< typeof Button > ) {
+	return (
+		<Button { ...buttonProps } label={ title } style={ { height: 'auto', textAlign: 'left' } }>
+			<HStack alignment="start">
+				<div style={ { flexShrink: 0 } }>
+					<Icon className="dashboard-add-new-site__menu-item-icon" icon={ icon } />
+				</div>
+				<VStack>
+					<Text>{ title }</Text>
+					<Text variant="muted">{ description }</Text>
path: client/dashboard/sites/add-new-site/menu-item.tsx
user: login: tellthemachines
body: Re avoiding the use of `preventWidows` as per the comment above, I'd suggest rendering Text `as="p"` here, so its contents get the default `text-wrap: pretty` applied to paragraphs. Also, given the structure it looks like a `p` is a better semantic match for this than a `span` which I believe is `Text`'s default element?
created_at: 2025-05-14T03:54:51Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,139 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import clsx from 'clsx';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import { preventWidows } from 'calypso/lib/formatting';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
+	return (
+		<HStack alignment="flex-start" style={ { padding: '16px' } } spacing={ 4 }>
+			<Column title={ __( 'Add new site' ) }>
+				<MenuItem
+					icon={ <WordPressLogo /> }
+					title={ __( 'WordPress.com' ) }
+					description={ preventWidows(
+						__( 'Build and grow your site, all in one powerful platform.' )
+					) }
+					onClick={ wordpressClick }
+					href="/start?source=sites-dashboard&ref=new-site-popover"
path: client/dashboard/sites/add-new-site/index.tsx
user: login: youknowriad
body: Using `page` will ensure a client side navigation if I import this component in the existing dashboard (to avoid duplication). But maybe it's ok to avoid it here.
created_at: 2025-05-14T09:05:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,42 @@
+import {
+	__experimentalVStack as VStack,
+	__experimentalHStack as HStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { Icon } from '@wordpress/icons';
+import React from 'react';
+
+type Props = {
+	children?: JSX.Element;
+	description: string;
+	title: string;
+	icon: JSX.Element;
+};
+
+function MenuItem( {
+	children,
+	description,
+	title,
+	icon,
+	...buttonProps
+}: Props & React.ComponentProps< typeof Button > ) {
+	return (
+		<Button { ...buttonProps } label={ title } style={ { height: 'auto', textAlign: 'left' } }>
+			<HStack alignment="start">
+				<div style={ { flexShrink: 0 } }>
+					<Icon className="dashboard-add-new-site__menu-item-icon" icon={ icon } />
path: client/dashboard/sites/add-new-site/menu-item.tsx
user: login: tyxla
body: I noticed that some of the icons have a hover state (the black icons), while others (the Jetpack icon) don't change on hover. Let's make them consistent.
created_at: 2025-05-14T14:29:16Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,42 @@
+import {
+	__experimentalVStack as VStack,
+	__experimentalHStack as HStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { Icon } from '@wordpress/icons';
+import React from 'react';
+
+type Props = {
+	children?: JSX.Element;
+	description: string;
+	title: string;
+	icon: JSX.Element;
+};
+
+function MenuItem( {
+	children,
+	description,
+	title,
+	icon,
+	...buttonProps
+}: Props & React.ComponentProps< typeof Button > ) {
+	return (
+		<Button { ...buttonProps } label={ title } style={ { height: 'auto', textAlign: 'left' } }>
path: client/dashboard/sites/add-new-site/menu-item.tsx
user: login: tyxla
body: I think the tooltip is redundant, since it repeats the menu item title:

![Screenshot 2025-05-14 at 17 33 35](https://github.com/user-attachments/assets/909cec00-901a-4109-8e4e-cd63fafa5d17)

The aria-label is useful, though, so perhaps we should specifically disable `showTooltip`?

created_at: 2025-05-14T14:40:50Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,128 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { useViewportMatch } from '@wordpress/compose';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
path: client/dashboard/sites/add-new-site/index.tsx
user: login: tyxla
body: The amount of duplication this creates with the existing "Add New Site" button is unfortunate. 

Isn't there a pathway towards reusing what exists already?

I'm OK with going as-is for the sake of pushing forward, but I want to be sure this is followed up on. The new "Add New Site" popup was designed to be modular, reusable, and composable, and if there's a reason to duplicate its code, it's something we need to reconcile and address sooner than later. 
created_at: 2025-05-14T14:45:37Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,128 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { useViewportMatch } from '@wordpress/compose';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
path: client/dashboard/sites/add-new-site/index.tsx
user: login: youknowriad
body: See PR description

>  the ultimate goal (either in this PR or a follow-up is to reuse this new rewritten component in the v1 dashboard too, that way we evolve it in a unique place).
created_at: 2025-05-14T15:14:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,128 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { useViewportMatch } from '@wordpress/compose';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
path: client/dashboard/sites/add-new-site/index.tsx
user: login: tyxla
body: Thanks - I saw it and I wasn't particularly happy with it. Not a blocker, but not ideal too - I wanted to be sure we'll follow up on it.
created_at: 2025-05-14T15:17:22Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,128 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { useViewportMatch } from '@wordpress/compose';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
path: client/dashboard/sites/add-new-site/index.tsx
user: login: youknowriad
body: I feel like I'm saying the same thing as you, so what are you not happy about?
created_at: 2025-05-14T15:23:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,128 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { useViewportMatch } from '@wordpress/compose';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
path: client/dashboard/sites/add-new-site/index.tsx
user: login: tyxla
body: "The ultimate goal" sounds like a far thing 😉 and I'd prefer to see unifying with the existing components something for the shorter term. Ideally, even in this PR. If that's what you mean, I think we're on the same page.  
created_at: 2025-05-14T16:08:41Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,128 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { useViewportMatch } from '@wordpress/compose';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
path: client/dashboard/sites/add-new-site/index.tsx
user: login: youknowriad
body: I see, it's not meant to sound far fetching, I don't plan to merge this PR before the component being usable in the dashboard v1. My hesitation is just whether the removal should be part of the same PR or not (because that one would be more impactful than the v2 update)
created_at: 2025-05-14T16:44:11Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,139 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import clsx from 'clsx';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import { preventWidows } from 'calypso/lib/formatting';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
+	return (
+		<HStack alignment="flex-start" style={ { padding: '16px' } } spacing={ 4 }>
+			<Column title={ __( 'Add new site' ) }>
+				<MenuItem
+					icon={ <WordPressLogo /> }
+					title={ __( 'WordPress.com' ) }
+					description={ preventWidows(
+						__( 'Build and grow your site, all in one powerful platform.' )
+					) }
+					onClick={ wordpressClick }
+					href="/start?source=sites-dashboard&ref=new-site-popover"
path: client/dashboard/sites/add-new-site/index.tsx
user: login: jsnajdr
body: You don't need `page` to ensure good behavior of "native" links like `<a href="...">`. If the component is used in existing Calypso UI that uses `page`, there is a global `onclick` listener (on `document`) that intercepts clicks on links and handles them using `page`:

https://github.com/Automattic/wp-calypso/blob/trunk/packages/calypso-router/src/index.js#L725

There is an opposite problem though: TanStack Router doesn't have such a global listener (it's a non-explicit somewhat intrusive hack, after all) and if you want your `<a href>` links to be handled by the router, you need to use the router's own `<Link>` component.

created_at: 2025-05-15T09:37:06Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,139 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import clsx from 'clsx';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import { preventWidows } from 'calypso/lib/formatting';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
+	return (
+		<HStack alignment="flex-start" style={ { padding: '16px' } } spacing={ 4 }>
+			<Column title={ __( 'Add new site' ) }>
+				<MenuItem
+					icon={ <WordPressLogo /> }
+					title={ __( 'WordPress.com' ) }
+					description={ preventWidows(
+						__( 'Build and grow your site, all in one powerful platform.' )
+					) }
+					onClick={ wordpressClick }
+					href="/start?source=sites-dashboard&ref=new-site-popover"
+				/>
+				<MenuItem
+					icon={ <JetpackLogo /> }
+					title={ __( 'Via the Jetpack plugin' ) }
+					description={ preventWidows( __( 'Install the Jetpack plugin on an existing site.' ) ) }
+					onClick={ jetpackClick }
+					href={ `/jetpack/connect?cta_from=${ TRACK_SOURCE_NAME }&cta_id=add-site` }
+				/>
+			</Column>
+			<Column title={ __( 'Migrate and import' ) }>
+				<MenuItem
+					icon={ reusableBlock }
+					title={ __( 'Migrate' ) }
+					description={ preventWidows(
+						__( 'Bring your entire WordPress site to WordPress.com.' )
+					) }
+					onClick={ migrateClick }
+					href="/setup/site-migration?source=sites-dashboard&ref=new-site-popover&action=migrate"
+				/>
+				<MenuItem
+					icon={ <Icon icon={ download } size={ 18 } /> }
+					title={ __( 'Import' ) }
+					description={ preventWidows(
+						__( 'Use a backup to only import content from other platforms.' )
+					) }
+					onClick={ importClick }
+					href="/setup/site-migration/create-site?source=sites-dashboard&ref=new-site-popover&action=import"
+				/>
+			</Column>
+
+			<Button
+				// Figure out localizeUrl
+				href="https://wordpress.com/setup/onboarding"
path: client/dashboard/sites/add-new-site/index.tsx
user: login: jsnajdr
body: `localizeUrl` is a self-contained function with (almost) no dependencies, so it's fine to use it.

However, there are dependencies: it has the `locale` second parameter which defaults to `getDefaultLocale()`, and that introduces a dependency on `@wordpress/i18n` and its `i18n` global. That's not bad, we use `@wordpress/i18n` anyway.

I'd recommend to use the reactive `useLocalizeUrl` variant which reads `i18n` from context.

One unfortunate thing is the `localeContext` context provider, which you have to mount. The bad thing about it is that it has a huge overlap with the context in `@wordpress/react-i18n`. These two context should be merged together. At this moment you have to mount both.

created_at: 2025-05-15T09:44:23Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,139 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import clsx from 'clsx';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import { preventWidows } from 'calypso/lib/formatting';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
+	return (
+		<HStack alignment="flex-start" style={ { padding: '16px' } } spacing={ 4 }>
+			<Column title={ __( 'Add new site' ) }>
+				<MenuItem
+					icon={ <WordPressLogo /> }
+					title={ __( 'WordPress.com' ) }
+					description={ preventWidows(
+						__( 'Build and grow your site, all in one powerful platform.' )
+					) }
+					onClick={ wordpressClick }
+					href="/start?source=sites-dashboard&ref=new-site-popover"
path: client/dashboard/sites/add-new-site/index.tsx
user: login: youknowriad
body: In this particular case, it's not a problem because all these links go outside the React Router and we don't really want/need client side navigation coming from v2.
created_at: 2025-05-15T09:46:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -32,7 +36,9 @@ module.exports = {
 							'@automattic/components/src/*',
 							'!@automattic/components/src/summary-button',
 							'!@automattic/components/src/core-badge',
+							'!@automattic/calypso-analytics',
 							'!@automattic/dataviews',
+							'!@automattic/number-formatters',
path: client/dashboard/.eslintrc.js
user: login: jsnajdr
body: Yes, `number-formatters` is a very new package that comes from Jetpack and is used in both repos. Totally recommended. (kudos @chriskmnds).

`calypso-analytics` is also a perfectly good package to use.


created_at: 2025-05-15T09:59:04Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,139 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import clsx from 'clsx';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import { preventWidows } from 'calypso/lib/formatting';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
+	return (
+		<HStack alignment="flex-start" style={ { padding: '16px' } } spacing={ 4 }>
+			<Column title={ __( 'Add new site' ) }>
+				<MenuItem
+					icon={ <WordPressLogo /> }
+					title={ __( 'WordPress.com' ) }
+					description={ preventWidows(
+						__( 'Build and grow your site, all in one powerful platform.' )
+					) }
+					onClick={ wordpressClick }
+					href="/start?source=sites-dashboard&ref=new-site-popover"
+				/>
+				<MenuItem
+					icon={ <JetpackLogo /> }
+					title={ __( 'Via the Jetpack plugin' ) }
+					description={ preventWidows( __( 'Install the Jetpack plugin on an existing site.' ) ) }
+					onClick={ jetpackClick }
+					href={ `/jetpack/connect?cta_from=${ TRACK_SOURCE_NAME }&cta_id=add-site` }
+				/>
+			</Column>
+			<Column title={ __( 'Migrate and import' ) }>
+				<MenuItem
+					icon={ reusableBlock }
+					title={ __( 'Migrate' ) }
+					description={ preventWidows(
+						__( 'Bring your entire WordPress site to WordPress.com.' )
+					) }
+					onClick={ migrateClick }
+					href="/setup/site-migration?source=sites-dashboard&ref=new-site-popover&action=migrate"
+				/>
+				<MenuItem
+					icon={ <Icon icon={ download } size={ 18 } /> }
+					title={ __( 'Import' ) }
+					description={ preventWidows(
+						__( 'Use a backup to only import content from other platforms.' )
+					) }
+					onClick={ importClick }
+					href="/setup/site-migration/create-site?source=sites-dashboard&ref=new-site-popover&action=import"
+				/>
+			</Column>
+
+			<Button
+				// Figure out localizeUrl
+				href="https://wordpress.com/setup/onboarding"
path: client/dashboard/sites/add-new-site/index.tsx
user: login: youknowriad
body: Thanks, just to recap, we discussed a bit in DM and it seems the add new site component is only used in the sites dashboard (v1 and v2) and both require the user to be logged in, this means that there's no need to localize these links at all.
created_at: 2025-05-15T10:01:20Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,139 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import clsx from 'clsx';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import { preventWidows } from 'calypso/lib/formatting';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
+	return (
+		<HStack alignment="flex-start" style={ { padding: '16px' } } spacing={ 4 }>
+			<Column title={ __( 'Add new site' ) }>
+				<MenuItem
+					icon={ <WordPressLogo /> }
+					title={ __( 'WordPress.com' ) }
+					description={ preventWidows(
+						__( 'Build and grow your site, all in one powerful platform.' )
+					) }
+					onClick={ wordpressClick }
+					href="/start?source=sites-dashboard&ref=new-site-popover"
+				/>
+				<MenuItem
+					icon={ <JetpackLogo /> }
+					title={ __( 'Via the Jetpack plugin' ) }
+					description={ preventWidows( __( 'Install the Jetpack plugin on an existing site.' ) ) }
+					onClick={ jetpackClick }
+					href={ `/jetpack/connect?cta_from=${ TRACK_SOURCE_NAME }&cta_id=add-site` }
+				/>
+			</Column>
+			<Column title={ __( 'Migrate and import' ) }>
+				<MenuItem
+					icon={ reusableBlock }
+					title={ __( 'Migrate' ) }
+					description={ preventWidows(
+						__( 'Bring your entire WordPress site to WordPress.com.' )
+					) }
+					onClick={ migrateClick }
+					href="/setup/site-migration?source=sites-dashboard&ref=new-site-popover&action=migrate"
+				/>
+				<MenuItem
+					icon={ <Icon icon={ download } size={ 18 } /> }
+					title={ __( 'Import' ) }
+					description={ preventWidows(
+						__( 'Use a backup to only import content from other platforms.' )
+					) }
+					onClick={ importClick }
+					href="/setup/site-migration/create-site?source=sites-dashboard&ref=new-site-popover&action=import"
+				/>
+			</Column>
+
+			<Button
+				// Figure out localizeUrl
+				href="https://wordpress.com/setup/onboarding"
path: client/dashboard/sites/add-new-site/index.tsx
user: login: jsnajdr
body: Yes, I got lost a bit in the (very interesting) details of `localizeUrl` and forgot to mention that you probably don't need it 😆 For a logged in user the primary source of the locale is the user account info. Specifying locale in the URL itself is mainly for logged-out users who are not yet signed up.
created_at: 2025-05-15T10:06:29Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,128 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { useViewportMatch } from '@wordpress/compose';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
path: client/dashboard/sites/add-new-site/index.tsx
user: login: youknowriad
body: Ok The PR is now ready to land IMO, I plan to replace the old component in a quick follow-up. That way we can revert just one part if something is wrong.
created_at: 2025-05-15T10:16:05Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,128 @@
+import { recordTracksEvent } from '@automattic/calypso-analytics';
+import { WordPressLogo, JetpackLogo } from '@automattic/components';
+import { formatNumber } from '@automattic/number-formatters';
+import {
+	__experimentalHStack as HStack,
+	__experimentalVStack as VStack,
+	__experimentalText as Text,
+	Button,
+} from '@wordpress/components';
+import { useViewportMatch } from '@wordpress/compose';
+import { __, sprintf } from '@wordpress/i18n';
+import { download, reusableBlock, Icon } from '@wordpress/icons';
+import devSiteBanner from 'calypso/assets/images/a8c-for-agencies/dev-site-banner.svg';
+import Column from './column';
+import MenuItem from './menu-item';
+import './style.scss';
+
+const TRACK_SOURCE_NAME = 'sites-dashboard';
+
+const wordpressClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_add' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'wordpress',
+	} );
+};
+const jetpackClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_jetpack' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'jetpack',
+	} );
+};
+const migrateClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'migrate',
+	} );
+};
+const importClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_import' );
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'import',
+	} );
+};
+const offerClick = () => {
+	recordTracksEvent( 'calypso_sites_dashboard_new_site_action_click_item', {
+		action: 'offer',
+	} );
+};
+
+function AddNewSite() {
path: client/dashboard/sites/add-new-site/index.tsx
user: login: tyxla
body: Sounds good, thanks!
created_at: 2025-05-15T11:01:55Z
author_association: MEMBER

PR comments:
user: login: github-actions[bot]
created_at: 2025-05-12T12:38:03Z
body: <details>
<summary>Calypso Live <a href="https://calypso.live?image=registry.a8c.com/calypso/app:build-144423">(direct link)</a></summary>
<table>
<tr>
<td>
<img src="https://chart.googleapis.com/chart?chs=150x150&cht=qr&chl=https%3A%2F%2Fcalypso.live%3Fimage%3Dregistry.a8c.com%2Fcalypso%2Fapp%3Abuild-144423%26flags%3Doauth&choe=UTF-8" />
</td>
<td>
<a href="https://calypso.live?image=registry.a8c.com/calypso/app:build-144423">https://calypso.live?image=registry.a8c.com/calypso/app:build-144423</a>
</td>
</tr>
</table>
</details>
<details>
<summary>Jetpack Cloud live <a href="https://calypso.live?image=registry.a8c.com/calypso/app:build-144423&env=jetpack">(direct link)</a></summary>
<table>
<tr>
<td>
<img src="https://chart.googleapis.com/chart?chs=150x150&cht=qr&chl=https%3A%2F%2Fcalypso.live%3Fimage%3Dregistry.a8c.com%2Fcalypso%2Fapp%3Abuild-144423%26env%3Djetpack%26flags%3Doauth&choe=UTF-8" />
</td>
<td>
<a href="https://calypso.live?image=registry.a8c.com/calypso/app:build-144423&env=jetpack">https://calypso.live?image=registry.a8c.com/calypso/app:build-144423&env=jetpack</a>
</td>
</tr>
</table>
</details>
<details>
<summary>Automattic for Agencies live <a href="https://calypso.live?image=registry.a8c.com/calypso/app:build-144423&env=a8c-for-agencies">(direct link)</a></summary>
<table>
<tr>
<td>
<img src="https://chart.googleapis.com/chart?chs=150x150&cht=qr&chl=https%3A%2F%2Fcalypso.live%3Fimage%3Dregistry.a8c.com%2Fcalypso%2Fapp%3Abuild-144423%26env%3Da8c-for-agencies%26flags%3Doauth&choe=UTF-8" />
</td>
<td>
<a href="https://calypso.live?image=registry.a8c.com/calypso/app:build-144423&env=a8c-for-agencies">https://calypso.live?image=registry.a8c.com/calypso/app:build-144423&env=a8c-for-agencies</a>
</td>
</tr>
</table>
</details>
<!--calypso-live-watermark:apr@v1-->
author_association: NONE
user: login: matticbot
created_at: 2025-05-12T12:44:47Z
body: **This PR modifies the release build for the following Calypso Apps:**

_For info about this notification, see here: PCYsg-OT6-p2_

* notifications
* wpcom-block-editor

To test WordPress.com changes, run `install-plugin.sh $pluginSlug add/new-site-dropdown-to-v2` on your sandbox.
<!--calypso-app-artifacts-watermark:apr@v1-->
author_association: CONTRIBUTOR
user: login: matticbot
created_at: 2025-05-12T12:45:34Z
body: <!-- icfy-watermark: c52822 -->
Here is how your PR affects size of JS and CSS bundles shipped to the user's browser:

**App Entrypoints** (~77 bytes added 📈 [gzipped])
<details>

```
name                    parsed_size           gzip_size
entry-dashboard-dotcom       +234 B  (+0.0%)      +56 B  (+0.0%)
entry-dashboard-a4a          +234 B  (+0.0%)      +56 B  (+0.0%)
entry-subscriptions          +126 B  (+0.0%)      +35 B  (+0.0%)
entry-stepper                +126 B  (+0.0%)      +35 B  (+0.0%)
entry-reauth-required        +126 B  (+0.0%)      +35 B  (+0.0%)
entry-main                   +126 B  (+0.0%)      +35 B  (+0.0%)
entry-login                  +126 B  (+0.0%)      +35 B  (+0.0%)
entry-domains-landing        +126 B  (+0.0%)      +35 B  (+0.0%)
entry-browsehappy            +126 B  (+0.1%)      +35 B  (+0.1%)
```

Common code that is always downloaded and parsed every time the app is loaded, no matter which route is used.
</details>

**Legend**
<details>
<summary>What is parsed and gzip size?</summary>

**Parsed Size:** Uncompressed size of the JS and CSS files. This much code needs to be parsed and stored in memory.
**Gzip Size:** Compressed size of the JS and CSS files. This much data needs to be downloaded over network.
</details>

Generated by performance advisor bot at [iscalypsofastyet.com](http://iscalypsofastyet.com).
author_association: CONTRIBUTOR
user: login: StevenDufresne
created_at: 2025-05-12T22:54:53Z
body: Tested, working as expected 👍. Added some non-blocking minor comments.
author_association: CONTRIBUTOR
user: login: youknowriad
created_at: 2025-05-14T07:45:43Z
body: > Or I guess we could leverage the direction property of HStack to render it as row or column conditional on screen size, but that would require checking the viewport size with JS which feels unnecessary if we can do it with CSS instead

I wonder if that's something that could be backed in VStack or HStack or a new ResponsiveStack component, it feels like a common behavior. 
author_association: CONTRIBUTOR
user: login: ntsekouras
created_at: 2025-05-14T08:40:33Z
body: >I wonder if that's something that could be backed in VStack or HStack or a new ResponsiveStack component, it feels like a common behavior.

I think HStack is really flexible and there are ways to control this mostly with `wrap`. The issue for me here is that the design is really specific to have 3 columns with specific width and then 'wrap' in single columns. 

I don't think we can avoid JS or CSS(simpler) to either change the direction or set the top HStack to `wrap` and update the width (something like 3*260) with a css media query.

I'm also curious what design updates we want for this. I couldn't find any new designs.
author_association: MEMBER