{{ product.price }}, a signed-in member sees their own price there.
A storefront page is cached once and served to everyone, so it can never contain one member’s price. Member pricing works around that: Fluid renders the public price into the cached HTML inside a small placeholder called a shell, and the SDK replaces the text once it has confirmed who is viewing.
What becomes member-aware
Any visible product or variant price you print:$48.00 and nothing else.
price, price_in_currency, and formatted_price are recognised on products and variants. A price needs a country to be resolvable, so a value with no country context prints plain.
Prices you print are hydrated. Prices you calculate with are not
This is the rule that keeps the rest of your theme working. A price becomes a shell only where it is printed as visible text. Everywhere else it stays the ordinary number or string it has always been:<script> and <style> bodies, JSON, and captured strings all keep scalar values. Only visible page text gets a shell, so your conditionals and your data attributes behave exactly as before.
Filters still apply
Filters on a printed price are carried with the shell and re-applied to the member’s price on Fluid’s side:assign compose with filters on the final output:
money, default, escaping, and text operations such as append, replace, and truncate are supported. Filters that load resources or build HTML are not, and an expression using one simply prints its public value with no shell. The browser never calculates money; it only writes the text Fluid returns.
You no longer need the member_price filter
Earlier releases required{{ product | member_price }} on every price you wanted hydrated. That is no longer necessary. Printing the price is enough.
The filter still works, so themes that already use it keep working and need no edit:
<fluid-member-price> element: a hand-written shell has no guaranteed fallback and no country, so the SDK cannot resolve it safely.
What the browser does
The SDK is one script that Fluid adds for companies with member storefront enabled. You do not add it to your layout. A guest costs nothing. The SDK looks for a small non-secret cookie that marks a signed-in session, and when it is absent it makes no requests at all — no session check, no price requests. Nothing about the page changes. For a signed-in member it confirms the session against Fluid, then asks for the prices the page needs and writes each one into its shell. Fluid resolves the price from the member’s own pricing tier using the signed-in cookie. The tier is never chosen in the browser and never appears in the page. Two details worth knowing:- The public price stays visible while requests run. There is no blanked-out or masked state. A member sees the public price briefly and then their own.
- Identical prices share one request. The same product printed twice on a page is resolved once. Different variants and different countries are always resolved separately.
When nothing changes
The public price staying on screen is the designed outcome of every failure, not an error:
Nothing writes an error into the page, and nothing is ever left blank.
What to do, and what not to
Member pricing works by replacing the text inside the element your theme prints the price into. Everything on this list follows from that one fact: if something else owns that text, it wins.Do
- Print the price and leave the element alone.
<p class="price">{{ product.price }}</p>is the whole requirement. - Let the price be the element’s own content. Hydration replaces text in place, so the price needs to be text on the page, not a value you stash and render later.
- Reserve space for the price so a longer or shorter member price does not shift the layout.
- Style on the resolution attributes rather than on the price text.
- Test with JavaScript disabled when a price does not personalise. That shows what the server actually sent, which separates a rendering problem from a theme-script problem.
Do not
- Do not render the price with your own script. Writing
{{ product.price }}into adata-attribute and then settingtextContentfrom it replaces the hydrated value with the public one. This is the single most common cause of a price that never personalises. - Do not set
textContentorinnerHTMLon an element that holds a price. Your write lands after hydration and silently undoes it. - Do not re-render the price container from client state — an AJAX section replace, or a component that redraws on variant change — unless you re-render from the server’s HTML.
- Do not do arithmetic on a price in the browser. Read the price, and let Fluid apply discounts, currency and rounding. A member price is not the public price times a factor.
- Do not cache a rendered price in a JavaScript variable,
localStorage, or a template you re-apply later. It belongs to one viewer and one session. - Do not hand-write a shell element. It has no guaranteed fallback and no country, so it cannot be resolved safely.
- Do not strip unknown elements or attributes. A sanitizer or optimiser that removes custom elements removes the price shell with them.
- Do not assume the price text at page load is the member’s. It is the public price until hydration completes, which is the point of the fallback.
Style around resolution
Each shell gainsdata-fluid-member-settled once it has either written a value or decided to keep the fallback. Section wrappers become resolved or guest.
Reserve space so a card does not shift when a longer or shorter price arrives:
Test member pricing
- Feature disabled. Render the page and confirm the output matches the version before any member work. No shells, no markers.
- Guest, feature enabled. Confirm the page looks identical. In the HTML, confirm shells carry the public price and the right
data-country-iso, and that your data attributes and JSON still hold plain numbers. - Signed-in member. Confirm prices swap to the member’s own. Sign out and confirm they revert.
Troubleshoot
Related
- Member greetings for greetings and member-only content with
{% member_name %}and{% member %}. - Sign in and sign out for the session these prices depend on.
- Account menu for a cached header that knows the member.