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
- 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
- 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_NAMEwith the real key or field name
- Embed the form on the post that holds the values and view the page — the fields arrive prefilled.
Smartcode Reference
| Smartcode | Reads |
|---|---|
{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 type | What {acf.FIELD_NAME} returns |
|---|---|
| Text, Text Area, Number, Range, Email, URL, Password | the value as-is |
| Select (single), Radio, Button Group | the selected value |
| Select (multiple), Checkbox | comma-separated list — red, blue |
| True / False | 1 when on, empty when off |
| Date Picker, Date Time Picker, Time Picker | the value in the field’s return format — 01/09/2026 |
| Color Picker | the color value |
| Post Object | the post title |
| Relationship | comma-separated post titles |
| Page Link | the URL |
| Taxonomy | the term name |
| User | the display name |
| Image, File | the URL |
| Gallery | comma-separated URLs |
| Link | the URL (not the link text) |
| Google Map | the address |
| Group | the first sub-field that looks like a label — see below |
| Repeater | one entry per row, comma-separated — see below |
| Flexible Content | best-effort like a repeater, usually empty — address a sub-field instead |
| Clone | depends 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_idor_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.orembed_post.before this feature ever sees it. A meta key likebudget.breakdowncontainsget.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.
Table of Contents