Skip to content

Shopify Dude Fix

Shopify Customer Accounts Show Logged In, but Liquid Customer Is Nil: A Storefront and App Proxy Fix Path

New customer accounts can appear signed in while a storefront Liquid customer or app proxy ID is missing. Diagnose session context and protect B2B/customer-gated features.

Type: Fix / Developer Guide · Stage: Optimize / Scale · Topic: Customer Accounts / B2B / App Proxies

On this page

Quick answer

A customer can appear signed in on Shopify’s customer-account pages while a storefront request renders customer as nil or an app proxy receives an empty logged_in_customer_id. Do not assume the customer Liquid object has been removed. Shopify’s current Liquid documentation still says it is available when a customer is logged in to the storefront. First reproduce the problem in the correct storefront session, then inspect the login entry point, domain, theme preview, browser session, and signed app-proxy request.

For a customer-gated or B2B portal, treat a missing customer identity as an unauthenticated request. Show a safe sign-in or retry state. Never grant access using a customer ID from localStorage, a query string supplied by the browser, or a previously cached company selection.

Why this problem is confusing

Shopify’s current customer accounts use a hosted, passwordless sign-in experience and account pages that are managed separately from the online store theme. The customer may navigate from a shopify.com account URL or a branded account subdomain back to the storefront. That does not mean every browser request has exactly the same authentication context.

Older tutorials assume a classic customer login form in templates/customers/login.liquid, a password field, and a predictable {% if customer %} check immediately after login. That code is still relevant to legacy account templates, but it is not the account UI architecture for current customer accounts. Shopify deprecated legacy customer accounts on February 26, 2026; they are no longer available to new stores or existing stores that were not using them.

There have also been genuine session-related reports. In June 2025, a Shopify staff member acknowledged a storefront customer-session issue and announced a fix for newly created sessions. Subsequent community reports described intermittent blank customer values and empty app-proxy customer IDs. Those reports justify testing the failure, not claiming that all current customer-account sessions are broken or that every store has the same root cause.

Separate the three identity surfaces

  1. Customer account page: Shopify’s hosted account experience may recognize the buyer. This is not itself proof that a particular online-store Liquid render has a non-nil customer object.
  2. Online-store Liquid: Shopify documents customer as globally accessible when a customer is logged in. A nil result means the request did not expose a logged-in customer to that Liquid render; it does not prove that the customer record is missing.
  3. App proxy: Shopify forwards a signed request to your app with parameters including shop, timestamp, signature, and logged_in_customer_id. Shopify documents the latter as empty when no customer is logged in. The backend must verify the signature before trusting any forwarded identity.

A theme’s customer object, an app proxy’s signed customer ID, and a customer-account extension’s authenticated context are related but not interchangeable. If a portal uses all three, test all three explicitly.

First: reproduce the storefront symptom

Use a development or test theme and render a small, temporary diagnostic element on a page that the affected customer can visit. Do not print names, email addresses, tags, or tokens into public diagnostics.

{% if customer %}
  <span data-account-debug="known">Customer recognized</span>
{% else %}
  <span data-account-debug="missing">Customer not present in Liquid</span>
{% endif %}

Check this on the actual storefront domain, not only inside a theme CLI local preview. Some developers have observed different session behavior between local preview and a shared Shopify theme preview URL. Also compare the published theme, a normal browser session, and an incognito session. Record which login link was used, whether the account page works, and whether returning to the store changes the result.

Use Shopify’s supported account routes rather than hard-coded legacy login forms. For a storefront-oriented login link, routes.storefront_login_url is documented; for a link to the account area, use routes.account_url. Do not create redirect loops that continually bounce customers between the store and the hosted account page.

Then: diagnose the app proxy separately

On the backend, log a minimal diagnostic record for each proxy request: timestamp, shop, signature verification result, whether logged_in_customer_id is present, and the requested operation. Avoid logging customer email, raw cookies, secrets, or the full signed query string in production logs.

Shopify’s proxy documentation explicitly says the forwarded request includes logged_in_customer_id when a customer is logged in and that the app must validate the SHA-256 HMAC signature. It also says app proxies do not forward cookies to your backend. Do not attempt to recover storefront authentication by reading a browser cookie on the proxy server; that cookie is not part of the forwarded request.

// Pseudocode: server-side proxy authorization sequence
const context = await verifyShopifyAppProxyRequest(request);
if (!context.valid) return forbidden();

const customerId = context.loggedInCustomerId;
if (!customerId) return signInRequired();

const allowedLocations = await loadAuthorizedCompanyLocations(customerId);
if (!allowedLocations.includes(requestedLocationId)) return forbidden();

return loadPortalData({ customerId, requestedLocationId });

The signature-verification function above is intentionally pseudocode. Use your app framework’s authenticated proxy helper or implement Shopify’s exact signing algorithm; do not invent an HMAC concatenation format from a generic example. A valid signature proves Shopify forwarded the request. It does not, by itself, authorize the customer to view an arbitrary company or order.

For B2B portals, preserve identity and authorization as separate checks

Sales-agent and wholesale portals often remember a selected company or company location between page loads. That is useful for the interface but not sufficient for access control. A persisted location ID is a preference, not proof of permission. Each backend read or write should verify the signed customer identity, then resolve that customer’s currently authorized company locations or permissions, then check the requested resource against that list.

When a customer session is temporarily missing, do not silently fall back to retail prices, an unrelated customer, or the last active company. A safer UI says sign-in is required or the session needs refreshing. The backend should refuse company-specific order history, pricing, draft-order creation, and other privileged operations until identity and authorization are established.

Migration checks before enabling customer accounts

  1. Inventory legacy customer templates, login modals, loyalty integrations, subscription links, and any theme Liquid gates using customer.
  2. Review Settings → Customer accounts and prepare the new account configuration in Settings → Checkout. Shopify’s upgrade guide recommends duplicating the configuration and testing it before upgrading.
  3. Choose the account domain deliberately. Shopify supports a single account domain across markets, not a separate customer-account domain for each market.
  4. Test a returning customer, a fresh login, a long-lived session, and a sign-out, including navigation from account pages back to the storefront.
  5. Test every app proxy action that uses customer identity. Confirm anonymous requests are denied, signed requests are verified, and company authorization is rechecked server-side.

Common misunderstanding

“New customer accounts removed the customer Liquid object.” Shopify’s current Liquid reference does not say that. The object is still documented for logged-in storefront customers. A nil value needs a session-context investigation, not a wholesale rewrite based on an incorrect universal rule.

“If the account page shows orders, the app proxy must have a customer ID.” That does not follow. Test the actual signed proxy request and handle an empty ID safely. Never substitute a client-supplied customer ID to make a gated page appear to work.

How to test this

  1. Sign in using the store’s supported customer-account link, then visit a storefront page with the temporary Liquid diagnostic.
  2. Repeat on the published theme and a shared preview URL; compare normal and incognito sessions.
  3. Navigate from account pages to the storefront immediately and again after an extended session; record any mismatch.
  4. Call a harmless app-proxy read endpoint and confirm whether the signed request includes a customer ID.
  5. Sign out, repeat the proxy call, and confirm company-specific data is denied.
  6. Try a company location that the test customer is not authorized for. The backend must reject it even if the browser sends a valid-looking location ID.
  7. Remove temporary diagnostics, preserve only non-sensitive operational logging, and document any reproducible platform issue for Shopify support.

Sources and further reading

Documentation reviewed October 13, 2026. Intermittent session reports are observations, not a claim of a universal unresolved Shopify defect.