Two features. One letter of difference in their name. Completely different jobs — and confusing them will break your automations.
Imagine you are writing a letter to every client you have ever booked — all at once.
Custom Values are the parts of that letter that never change. Your return address. Your studio name. Your phone number at the bottom. Your booking page URL. You write those once and they print the same on every single letter. That is a Custom Value — it belongs to your business, not to her.
Custom Fields are the parts that are different for each person. Her name. Her session date. The collection she chose. How many images she ordered. You pull those from her individual record and they print differently on each letter. That is a Custom Field — it belongs to her contact record.
Using a Custom Value: Your session at {{custom_values.studio_name}} is confirmed → prints as "Your session at Moonlight and Lace Boudoir is confirmed" for every single client. Same every time.
Using a Custom Field: {{contact.first_name}}, your session is on {{contact.session_date}} → prints as "Sarah, your session is on August 14" for Sarah and "Jasmine, your session is on September 3" for Jasmine. Different for each person.
This is one of the most common points of confusion in GHL and it has burned a lot of photographers. You go to build a funnel page — a thank-you page, a booking confirmation page, a session prep page — and you try to personalize it with her name or her session date using a Custom Field merge tag. It does not populate. It either shows the raw tag code or it shows nothing at all.
This is not a bug. It is a fundamental architectural limitation of how GHL funnels work.
Here is why: when a contact views a funnel page, GHL renders that page as a static web page served to anyone who visits the URL. There is no active session or logged-in context that tells GHL which specific contact is viewing it at that moment. Because GHL cannot identify which contact record to pull from, it cannot populate contact-specific Custom Fields. The page has no way to know whether it is Sarah or Jasmine opening it.
Custom Values work in funnels because they do not belong to any contact — they belong to your account. GHL renders them at the account level before serving the page. No contact identification needed.
The workaround: if you need personalized content on a funnel page, deliver it through an email or SMS instead. The email fires after the funnel form submission, pulls her Custom Fields correctly, and delivers the personalized content in her inbox — where contact-level merge tags work perfectly. Your funnel page itself uses Custom Values for your studio info, and your follow-up email handles everything personal.
{{custom_values.studio_name}} — Moonlight and Lace Boudoir. Same in every email forever.
{{custom_values.photographer_name}} — Deanna. Same signature on every automated message.
{{custom_values.studio_phone}} — Your studio number. Every SMS footer.
{{custom_values.booking_link}} — Your booking page URL. One change updates every single email that links to it.
{{custom_values.session_fee}} — $600. Change it once when your pricing changes. Every email that mentions the session fee updates automatically.
{{custom_values.instagram_handle}} — @moonlightandlaceboudoir. Every email footer that links to Instagram.
{{custom_values.studio_address}} — Your street address for parking instructions and session day emails.
{{contact.first_name}} — Already built in. Her first name. Personalize every single message.
{{contact.session_date}} — Her specific session date. Pulled from your calendar or intake form into her contact record.
{{contact.collection_choice}} — Which collection she booked. Used in confirmation and prep emails.
{{contact.payment_plan_start}} — Her first installment date. Used in payment reminder workflows.
{{contact.referral_source}} — Who sent her. Used to trigger your referral thank-you workflow.
{{contact.session_prep_notes}} — Anything specific she mentioned in her intake form. Used to personalize her pre-session email.
{{contact.total_investment}} — Her final order total. Used in the thank-you and delivery confirmation email.
Go to Settings → Custom Values in your GHL account left sidebar. Click + Add Custom Value. Give it a name (e.g. "Studio Name") and a value (e.g. "Moonlight and Lace Boudoir"). Click Save. GHL will generate the merge tag automatically — it will look like {{custom_values.studio_name}}. Copy that tag and use it anywhere in your emails, SMS, and workflows.
Go to Settings → Custom Fields → Contacts. Click + Add Field. Choose the field type — Text for names and free-form answers, Date/Time for session dates, Number for dollar amounts, Dropdown for fixed choices like collection names. Name it clearly. The merge tag will look like {{contact.your_field_name}}. This field now appears on every contact record and can be filled in manually, via a form, or by a workflow action.
Inside any workflow, add an Update Contact Field action. Choose the Custom Field you want to fill. Set the value — either a static value, a merge tag from another field, or a dynamic value from the trigger event. This is how your booking page automatically populates her session date, her collection choice, and her payment plan details into her contact record without you touching anything.
In any email or SMS in GHL, click the { } merge tag button or type double curly braces. You will see a dropdown of all available tags — both Custom Values (under Custom Values) and Custom Fields (under Contact). Select the one you want. GHL inserts the tag. When the message sends, it replaces the tag with the actual value for that specific contact. If the field is empty for a contact, the tag renders as blank — so always make sure the field is populated before a message that uses it fires.
If you create a Custom Field called "Studio Name" and manually type "Moonlight and Lace Boudoir" on each contact record, you have to update every single contact if your studio name ever changes. Put anything that belongs to your business — not to her — in Custom Values. One update. Done.
Adding {{contact.first_name}} to your funnel thank-you page and wondering why it shows the raw tag instead of her name. GHL funnels cannot identify which contact is viewing them. Move the personalized content into an email that fires immediately after the funnel form is submitted. The email handles personalization perfectly.
Your session confirmation email pulls {{contact.session_date}} but the workflow fires before that field gets filled in. She receives an email that says "Your session is on ." — blank. Always use a workflow condition to check that the field is not empty before any message that depends on it fires.
You change your session fee Custom Value from $500 to $600 in the middle of a follow-up campaign. Every email that fires after that change — including follow-ups to leads who inquired when your fee was $500 — now says $600. Custom Values are global and instantaneous. If you are running active campaigns that reference a specific dollar amount, create a separate Custom Value for it rather than editing the existing one mid-campaign.
After six months of building in GHL you end up with 40 Custom Fields and you cannot remember which ones are still active, which ones are duplicates, and which ones were created by accident. Name every Custom Field with a prefix that tells you what it belongs to. Session_ for session-related fields. Payment_ for payment fields. Intake_ for intake form answers. This makes filtering and finding them infinitely easier.
Every time you are about to create something in GHL, ask one question: is this the same for every contact, or is it specific to her? Same for everyone = Custom Value. Specific to her = Custom Field. That one question solves 90% of the confusion — and it will save you from the funnel headache before it happens.