function mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id) {
if (($form_id == 'profile_customer_edit_form') || ($form_id == 'profile_customer_add_form')) {
$form['address']['widget'][0]['address']['#pre_render'][] = \Drupal\my_module\Callback\CustomerProfileCallback::class . '::limitAdministrativeAreas';
}
<?php
namespace Drupal\my_module\Callback;
use Drupal\Core\Security\TrustedCallbackInterface;
class CustomerProfileCallback implements TrustedCallbackInterface {
public static function trustedCallbacks() {
return ['limitAdministrativeAreas'];
}
/**
* Pre-render callback
*/
public function limitAdministrativeAreas(array $element): array {
if ($element['country_code']['#default_value'] == 'US') {
$include_states = ['', 'NY', 'NJ', 'PA', 'DE', 'MD', 'DC', 'VA', 'WV'];
$options = array_intersect_key($element['administrative_area']['#options'], array_flip($include_states));
$element['administrative_area']['#options'] = $options;
}
return $element;
}
}
https://github.com/centarro/commerce-docs/blob/67a2f85bf151a141df04ac90afd43e6dd4573a30/docs/v2/developer-guide/customers/addresses.md?plain=1#L326C115-L326C283 mentions how to modify the form via #pre_render callback. Core updated requirements for this a while back, so they cannot be defined as simple function. They must be defined either as an anonymous function (which doesn't work due to field serialization on ajax from country selection) or via a class implementing TrustedCallbackInterface. So something like