Prefill from Post Meta & ACF

Updated: 

Prefill form fields with values from the post or page the form is embedded on — or from any other public post — using {post_meta.YOUR_META_KEY} and {acf.YOUR_FIELD_NAME} smartcodes.

Fluent Forms already ships {embed_post.meta.KEY} and {embed_post.acf.KEY}, but both return an empty string for any value that is not a plain string or number. That rules out most of ACF: checkboxes, multi-selects, relationships, post objects, taxonomies, users, images, galleries and links all prefill as empty. And neither can read from a post other than the one the form sits on.

These smartcodes fill both gaps: complex values are formatted into something readable, and any public post can be targeted by ID.

Use Cases

  • Context-aware forms – One “Request a quote” form embedded on many product pages, each submission carrying the product’s SKU, price or category from ACF.
  • Event registrations – A single registration form on every event page, prefilling the event date, venue and speaker list.
  • Job applications – The job post’s reference number and department travel with the application, so the entry is self-describing.
  • Central settings post – Keep a campaign code, deadline or price list on one hidden-in-plain-sight post and pull it into every form by ID.
  • Hidden tracking fields – Prefill a hidden field so the source post’s data lands in the entry, email notifications, PDFs and webhooks without asking the visitor anything.

Setup Instructions

  1. Enable the feature
    • Navigate to WordPress Dashboard → Settings → Form Enhancer
    • Open the Fluent Forms tab and scroll to FEATURES
    • Toggle Prefill from Post Meta & ACF ON and save
  2. Use a smartcode as a field’s default value
    • Open the form in Fluent Forms → Editor
    • Select a field and open Advanced Options
    • In Default Value, type the smartcode — or pick it from the smartcode dropdown (the ⋮ button) under Current Post (Form Enhancer), which offers Post Meta Value and ACF Field Value
    • Replace YOUR_META_KEY / YOUR_FIELD_NAME with the real key or field name
  3. Embed the form on the post that holds the values and view the page — the fields arrive prefilled.

Smartcode Reference

SmartcodeReads
{post_meta.YOUR_META_KEY}a custom field of the post the form is embedded on
{acf.YOUR_FIELD_NAME}an ACF/SCF field of the post the form is embedded on
{post_meta.123.YOUR_META_KEY}a custom field of post ID 123
{acf.123.YOUR_FIELD_NAME}an ACF/SCF field of post ID 123

A leading number is always read as a post ID. If your meta key is itself a number, {post_meta.99} still means “the key 99 on the current post” — only {post_meta.99.something} targets post 99.

Where the smartcodes work

They are resolved when the form is rendered, so they work anywhere in the form’s HTML — not only in Default Value:

  • Default Value of any input (text, email, number, hidden, textarea, dropdown…)
  • Placeholder text
  • Field labels and help messages
  • Custom HTML blocks and section breaks

They are not available in email notifications, confirmation messages, PDFs or webhooks — those run after submission, where there is no page context any more. You don’t need them there: a prefilled value is submitted like anything the visitor typed, so {inputs.your_field_name} gives you the same value in every integration.

Values from Another Post

Prepend a post ID to read from a different post than the one the form is on:

{post_meta.123.campaign_code}
{acf.123.price_list}

The targeted post must be published and publicly viewable, and must not be password-protected. Drafts, pending, private, trashed, scheduled and password-protected posts all resolve to an empty value — including for logged-in administrators. The reason is that the resolved value is written into the form’s HTML for every visitor, so anything readable this way is effectively public.

ACF Field Types

ACF field typeWhat {acf.FIELD_NAME} returns
Text, Text Area, Number, Range, Email, URL, Passwordthe value as-is
Select (single), Radio, Button Groupthe selected value
Select (multiple), Checkboxcomma-separated list — red, blue
True / False1 when on, empty when off
Date Picker, Date Time Picker, Time Pickerthe value in the field’s return format — 01/09/2026
Color Pickerthe color value
Post Objectthe post title
Relationshipcomma-separated post titles
Page Linkthe URL
Taxonomythe term name
Userthe display name
Image, Filethe URL
Gallerycomma-separated URLs
Linkthe URL (not the link text)
Google Mapthe address
Groupthe first sub-field that looks like a label — see below
Repeaterone entry per row, comma-separated — see below
Flexible Contentbest-effort like a repeater, usually empty — address a sub-field instead
Clonedepends on the cloned field; address the cloned sub-field by its own name

Fields returning an ID or array of IDs (when the field’s Return Format is set to ID) resolve to the ID number(s), which is what you usually want in a hidden field.

Groups and Repeaters

{acf.GROUP_NAME} and {acf.REPEATER_NAME} return a best-effort summary: for each row or group, the first sub-field named url, title, name, label or address wins. A repeater of speakers whose sub-field is called name gives Alice, Bob; the same repeater with a sub-field called speaker_name gives nothing.

Address a specific sub-field instead — ACF’s own selector syntax works:

{acf.venue_city}          → the "city" sub-field of the "venue" group
{acf.speakers_0_name}     → the "name" sub-field of the repeater's first row

ACF field keys also work in place of names, if you prefer them: {acf.field_65b1c2d3e4f56}.

Security

  • Protected meta is never exposed. Keys WordPress treats as protected — anything starting with an underscore, such as _edit_lock, _thumbnail_id or _wp_page_template — resolve to empty in both {post_meta.*} and {acf.*}, including through ACF’s fallback to raw meta.
  • Only public posts can be targeted by ID, as described above.
  • Every value is escaped before it reaches the page, so HTML or quotes stored in a custom field cannot break out of the input.
  • Worth knowing: anyone who can edit a form can read any non-underscore custom field of any published post through {post_meta.ID.KEY}. Published content is already public, so this matches what the site exposes anyway — but if a plugin on your site stores something sensitive in a normally-named meta key, add it to WordPress’ protected list:
add_filter('is_protected_meta', function ($protected, $metaKey, $metaType) {
    if ('post' === $metaType && in_array($metaKey, ['api_token', 'internal_notes'], true)) {
        return true;
    }
    return $protected;
}, 10, 3);

The feature is off by default, so nothing is readable until you turn it on.

Limitations

  • Requires ACF or SCF for the {acf.*} smartcodes. {post_meta.*} works on any WordPress site — ACF is not needed.
  • Reserved key names. Fluent Forms’ own parser claims any smartcode containing get., user., date., cookie., dynamic., random_string. or embed_post. before this feature ever sees it. A meta key like budget.breakdown contains get. and will never resolve. Rename the key, or read it with an explicit post ID under a different name.
  • The form needs a post context. Without an explicit post ID the value comes from the post currently being rendered. On a page that is not a single post — a search results page, a 404, a form on a standalone Fluent Forms landing page, or a form loaded into a popup by AJAX — there may be no post, or the wrong one (the last post of a loop). Use the {post_meta.123.KEY} form when the form is not embedded in the post’s own content.
  • Values are resolved at render time, so a full-page cache stores them along with the rest of the HTML. If a form is embedded on a cached page, every visitor gets the version that was cached. This is only a concern if the underlying meta changes often.
  • Non-scalar leftovers. Objects other than posts, terms and users, and arrays that contain none of the recognised keys, resolve to empty rather than to something like Array.
  • No user meta. Fluent Forms already ships {user.meta.KEY} for the logged-in user’s meta — use that.

Notes

  • The feature is off by default. While it is off the smartcodes are inert and stay on the page as literal text, so turning it off again is a clean rollback.
  • A missing key, a missing post, or an empty value all resolve to an empty string — never to a visible {post_meta.…} leftover, as long as the feature is on.
  • Prefilled values are ordinary field values: the visitor can edit them (use a hidden field if that matters), validation applies to them, and they are stored in the entry.
  • Works with both the free and PRO versions of Fluent Forms, and with both the free and PRO versions of Form Enhancer.