---
title: Address
description: "Stores a structured address as an object using an international format (V1). The field renders multiple inputs (street, city, state, postal code, country) and saves a single structured value, including a pre-built formatted string for display or search. ## Use…"
url: "https://racmanuel.dev/docs/custom-fields-booster/address/"
updated: "2026-02-24"
category: Custom Fields Booster
tags:
  - Free
---

# Address

Stores a structured address as an object using an international format (V1).

The field renders multiple inputs (street, city, state, postal code, country) and saves a single structured value, including a pre-built formatted string for display or search.

## Use Cases

- Collect shipping or billing-style addresses
- Store contact or location addresses for directories, CPTs, or users
- Save addresses in a structured format for integrations (ERP/CRM/SAP)
- Normalize country values using ISO2 codes
- Provide a formatted address string for display or search

## Field Preview

A multi-line address form UI:

- Street address (line 1)
- Optional street line 2
- City
- Optional state / province
- Optional postal code
- Country dropdown (ISO2)

## How to Use

1. Add the Address field to a Field Group.
2. (Optional) Set **Default country (ISO2)** (example `MX`).
3. Choose which optional inputs should be visible (street 2, state, postal code).
4. Choose which inputs are required (street 1, city, country).
5. Save the Field Group and edit a post (or render it in `acf_form`).
6. No custom code is required.

## Field Settings

| Setting | Description | Default |
| --- | --- | --- |
| Default country (ISO2) | ISO2 code used when no country is selected | Empty |
| Show optional fields | Controls optional inputs visibility (street 2, state, postal code) | All enabled |
| Required fields | Controls required validation rules (street 1, city, country) | street 1 + city + country |

Notes:

- Country values are stored as ISO2 codes (example `MX`, `US`).
- Country list is loaded from an internal JSON file (`countries.json`).

## Value & Storage

Saved as: Post meta

Storage type: Structured array (object)

Return format: array (or empty array when missing/invalid)

| REST format: object | null |
| --- | --- |

Country format: ISO2 uppercase

Additional field: `formatted` is saved automatically

Saved structure:

- `street_1` (string)
- `street_2` (string)
- `city` (string)
- `state` (string)
- `postcode` (string)
- `country` (string, ISO2)
- `formatted` (string, multi-line)

Important details:

- Hidden optional fields are saved as empty strings.
- `formatted` is regenerated during save based on current settings and values.
- `formatted` is intended for display/search, not as a replacement for the structured fields.

## Output Examples

### PHP (Get full address object)

```php
$address = get_field('my_address');

if (is_array($address)) {
    echo nl2br(esc_html($address['formatted'] ?? ''));
}
```

### PHP (Access individual parts)

```php
$address = get_field('my_address');

$city    = is_array($address) ? ($address['city'] ?? '') : '';
$country = is_array($address) ? ($address['country'] ?? '') : '';

echo esc_html($city . ', ' . $country);
```

### Twig

```php
{% set address = fn('get_field', 'my_address') %}
{{ address.formatted|default('') }}
```

## Compatibility

- Repeaters
- Flexible Content
- Options Pages
- Frontend forms (acf_form)
- REST API (schema, formatting, validation)
- Multisite

## Hooks (Developer)

### Hooks Summary

| Hook | Type | Purpose |
| --- | --- | --- |
| custom_fields_booster_address_defaults | Filter | Modify default settings and placeholders. |
| custom_fields_booster_address_supports | Filter | Modify ACF support flags. |
| custom_fields_booster_address_before_settings | Action | Run logic before rendering settings UI. |
| custom_fields_booster_address_after_settings | Action | Run logic after rendering settings UI. |
| custom_fields_booster_address_before_enqueue | Action | Run logic before enqueuing assets. |
| custom_fields_booster_address_after_enqueue | Action | Run logic after enqueuing assets. |
| custom_fields_booster_address_before_render | Action | Run logic before rendering UI. |
| custom_fields_booster_address_after_render | Action | Run logic after rendering UI. |
| custom_fields_booster_address_update_value | Filter | Modify the value before saving. |
| custom_fields_booster_address_load_value | Filter | Modify the value after loading. |
| custom_fields_booster_address_validate_value | Filter | Modify validation result. |
| custom_fields_booster_address_format_value | Filter | Modify value returned by `get_field()`. |

### Filters

#### Defaults

**Filter:** `custom_fields_booster_address_defaults`

Purpose: Override default placeholders, required flags, and visible fields.

When: You want consistent defaults across all Address fields.

```php
add_filter('custom_fields_booster_address_defaults', function ($defaults) {
    $defaults['default_country'] = 'MX';
    $defaults['require_country'] = 1;
    $defaults['show_postcode'] = 0;
    return $defaults;
});
```

#### Supports

**Filter:** `custom_fields_booster_address_supports`

Purpose: Control ACF supports such as required or escaping behavior.

When: Your project needs different support flags.

```php
add_filter('custom_fields_booster_address_supports', function ($supports) {
    $supports['required'] = false;
    return $supports;
});
```

#### Update Value

**Filter:** `custom_fields_booster_address_update_value`

Purpose: Modify the sanitized structured address before it is saved.

When: You need normalization, enrichment, or compatibility transformations.

```php
add_filter('custom_fields_booster_address_update_value', function ($out, $post_id, $field) {
    if (!empty($out['country'])) {
        $out['country'] = strtolower($out['country']);
    }

    return $out;
}, 10, 3);
```

#### Load Value

**Filter:** `custom_fields_booster_address_load_value`

Purpose: Modify the value after loading from storage.

When: You want to normalize missing keys or apply defaults on load.

```php
add_filter('custom_fields_booster_address_load_value', function ($value, $post_id, $field) {
    return is_array($value) ? $value : array();
}, 10, 3);
```

#### Validate Value

**Filter:** `custom_fields_booster_address_validate_value`

Purpose: Modify the validation result.

When: You need custom validation logic.

```php
add_filter('custom_fields_booster_address_validate_value', function ($valid, $value, $field, $input) {
    return $valid;
}, 10, 4);
```

#### Format Value (Return)

**Filter:** `custom_fields_booster_address_format_value`

Purpose: Modify value returned by `get_field()` and REST output formatting.

When: You want to normalize missing keys or add computed keys.

```php
add_filter('custom_fields_booster_address_format_value', function ($value, $post_id, $field) {
    $value = is_array($value) ? $value : array();

    $value += array(
        'street_1' => '',
        'street_2' => '',
        'city' => '',
        'state' => '',
        'postcode' => '',
        'country' => '',
        'formatted' => '',
    );

    return $value;
}, 10, 3);
```

### Actions

#### Before Render

**Action:** `custom_fields_booster_address_before_render`

Runs before rendering the field UI and provides the countries dataset.

```php
add_action('custom_fields_booster_address_before_render', function ($field, $countries) {
    // Pre-render logic.
}, 10, 2);
```

#### After Render

**Action:** `custom_fields_booster_address_after_render`

Runs after rendering the field UI and provides the countries dataset.

```php
add_action('custom_fields_booster_address_after_render', function ($field, $countries) {
    // Post-render logic.
}, 10, 2);
```

## Assets

This field enqueues styles whenever the input is rendered (admin and frontend via `acf_form()`):

- `admin/css/cfb-field-address.css`

## REST API

| Schema: object | null |
| --- | --- |

Properties: `street_1`, `street_2`, `city`, `state`, `postcode`, `country`, `formatted`

Notes: `formatted` is included in REST output when available.

Example REST output:

```php
{
  "my_address": {
    "street_1": "Av. Siempre Viva 742",
    "street_2": "Depto 4B",
    "city": "Merida",
    "state": "Yucatan",
    "postcode": "97000",
    "country": "MX",
    "formatted": "Av. Siempre Viva 742\nDepto 4B\nMerida, Yucatan, 97000\nMX"
  }
}
```

## REST Validation

- `null` is allowed.
- Non-array values are rejected with a validation error message.

## Security & Escaping

- Values are sanitized on save using `sanitize_text_field()`.
- Country codes are normalized to uppercase.
- Output should be escaped in templates (`esc_html`, `nl2br`, etc.).
- `escaping_html` support is set to false to avoid unwanted transformations in structured values.

## Notes / Limitations

- This field stores a structured value, not a single string.
- `formatted` is generated at save time and depends on visibility settings.
- Hidden optional fields are saved as empty strings.
- Country list depends on the internal `countries.json` dataset and must contain ISO2 codes.

## Changelog

- 1.0.0 — Initial release
