To update a repeater field created with Advanced Custom Fields programmatically you’ll need to use the update_field() function.
Populating Untouched/Unsaved Repeater Fields
The following approach will pre-populate an ACF field using the $rows array. The field ID provided in this example is repeat-field-id, replace this with your field ID when you programmatically update the field.
$rows = [
[
'title' => 'Something Great',
'label' => 'Great.org',
'url' => 'https://great.org',
],
[
'title' => 'Even Better',
'label' => 'Better.org',
'url' => 'https://better.org',
],
[
'title' => 'Better Still',
'label' => 'BetterStill.com',
'url' => 'https://betterstill.com',
],
];
update_field( 'repeater-field-id', $rows );
ACF provides an internal function for this, add_row(), but it doesn’t actually work if you want to inject values into a new, untouched ACF repeater field. To do this, we need to add the array directing into the field value.
Appending Values to Existing Repeater Fields
add_row() will work for adding existing rows to an already saved ACF repeater field, but it’s not an option if you want to place something in a specific spot or add and remove items at the same time. To gain this added flexibility we can use a modified version of the approach above.
$existing = get_field( 'repeater-field-id' );
if ( ! is_array($existing) ) $existing = [];
$additions = [
[
'title' => 'Something Great',
'label' => 'Great.org',
'url' => 'https://great.org',
],
[
'title' => 'Even Better',
'label' => 'Better.org',
'url' => 'https://better.org',
],
[
'title' => 'Better Still',
'label' => 'BetterStill.com',
'url' => 'https://betterstill.com',
],
];
$updated = array_merge( $existing, $additions );
update_field( 'repeater-field-id', $updated );
This approach will add 3 new rows after any existing values. If no values exist, the 3 new rows will still be saved.
One important detail here: use array_merge(), not the + array union operator. Both arrays have numeric keys starting at 0, and + keeps the left-hand array’s values for any colliding key, which means your additions silently disappear whenever rows already exist. array_merge() reindexes and appends, which is what you actually want.
Updating a Single Sub Field
When you only need to change one value inside one row, skip rewriting the whole repeater and use update_sub_field() with the row index (rows are 1-based, not 0-based):
// Change the title of the second row
update_sub_field( [ 'repeater-field-id', 2, 'title' ], 'A Better Title', $post_id );
Removing Rows
Deleting rows follows the same read-modify-write pattern. Filter out what you don’t want and save the result back:
$rows = get_field( 'repeater-field-id', $post_id ) ?: [];
// Remove any row pointing at a specific URL
$rows = array_values( array_filter( $rows, function ( $row ) {
return $row['url'] !== 'https://great.org';
} ) );
update_field( 'repeater-field-id', $rows, $post_id );
// Or clear the repeater entirely
update_field( 'repeater-field-id', [], $post_id );
The array_values() call matters: it reindexes the array after filtering so ACF stores a clean sequential set of rows.
Field Names vs Field Keys
If the post you’re updating has never been saved with the field group in the admin, passing the field name (repeater-field-id) can fail silently because ACF hasn’t written its internal reference meta yet. In that situation use the field key instead, the field_abc123 identifier visible in the field group editor, for both the repeater and its sub fields:
update_field( 'field_5f1a2b3c4d5e6', $rows, $post_id );
Field keys always work; field names only work once ACF knows which field group the value belongs to. For import scripts and programmatic content creation, keys are the safe default.
Conclusion
If you want to update a repeater field in ACF programmatically then this approach is the best way to do it. add_row() just isn’t flexible enough for most of the use cases I come across when supporting custom WordPress websites. I commonly use these approach to sync up content between staging and live environments, or my local environment and a live site.