Skip to main content
A headless storefront is a site you build and host yourself that sells through Fluid. Fluid stays the source of truth for products, content, carts, checkout, and rep attribution. Your app decides how the store looks and where it runs. Fluid publishes a starter you can copy: Fluid-WeCommerce/headless-wecommerce, a Next.js app under the MIT license. Set one environment variable to your company’s Fluid subdomain and it renders the whole storefront: home, shop, products, enrollment packs, media, libraries, categories, collections, blog, pages, cart, and search.

Consider a Fluid theme first

We don’t recommend a headless storefront unless you need one. A Fluid theme gives you full control of the design, and a headless storefront gives up a lot in return:
  • No editing in the builder. Your teammates can’t change the storefront in Fluid’s page editor. Every change goes through a developer and your code.
  • No droplets or marketplace items. Droplets and other marketplace items can’t attach to a headless storefront.
  • No bots. Fluid’s bots can’t review your storefront’s SEO or make edits for you.
  • You pay for hosting. Your servers and their costs are yours to run. Fluid themes are served free from a global CDN.
  • No built-in agentic commerce. A headless storefront doesn’t include the agentic commerce features, such as UCP (Universal Commerce Protocol), that Fluid storefronts have from the start.
Go headless only when it’s absolutely required.
This guide covers a storefront that uses Fluid’s hosted checkout. To build the checkout yourself as well, see Build a headless checkout.

How it fits together

The starter splits the work between your server, the browser, and Fluid: The app reads only the public storefront endpoints, which need no token. See Public and company endpoints.

Run it locally

You need Node.js 20.9 or later, pnpm, and your company’s Fluid subdomain: acme if your store is at acme.fluid.app.
1

Copy the starter

2

Point it at your company

Copy the example settings and set FLUID_SHOP to your subdomain.
.env.local
3

Start the dev server

Open http://127.0.0.1:3000. You see your store’s products, content, languages, countries, and brand colors.
Test checkout at http://127.0.0.1:3000, not http://localhost:3000. On a hostname that contains localhost, the SDK sends checkout to a local Fluid checkout server instead of Fluid’s hosted checkout. Deployed sites aren’t affected.

Deploy it

The starter is a standard Next.js app, so it runs anywhere Next.js does.
  • Vercel. Use the Deploy button in the repository’s README, or import the repository, and set FLUID_SHOP. Add your domain under the project’s domains. Canonical URLs and the sitemap follow the production domain.
  • Any Node.js host. Run pnpm build, then pnpm start. Set NEXT_PUBLIC_SITE_URL to the storefront’s public URL so canonical URLs and the sitemap use it.

Settings

Only FLUID_SHOP is required. .env.example lists every setting.

URLs and rep credit

Pages use the same URLs as a Fluid-hosted storefront, so existing links, shares, and QR codes keep working. Every page sits behind the credit segment: a rep’s username, such as /jordan-lee/products/beet-blend, or home when no rep is named, such as /home/products/beet-blend. Links keep the shopper’s credit. A shopper who arrives on /jordan-lee/shop stays on /jordan-lee/... as they browse, and the SDK attributes the visit to that rep. Canonical URLs and the sitemap use /home/.... See Storefront URLs and the credit path.

Build your own templates

The starter has a folder under src/templates for each Fluid template type, such as product, enrollment_pack, medium, library, collection, category, post, and page, plus the page types such as home_page, shop_page, and cart_page. Each folder has a default.tsx and an index.ts that registers its templates. A record picks its template by its slug:
  1. If the folder’s index.ts registers a template under the record’s slug, that template renders.
  2. Otherwise, default renders.
src/templates/product/index.ts
The template a merchant picks in Fluid Admin isn’t used. Your storefront’s design lives in your code. If a merchant changes a record’s slug, update the key or the record goes back to default. See Slugs and URLs. Templates are built from sections in src/sections, which are built from components in src/components, the same layering as a Fluid theme.

Languages and countries

The storefront offers the languages and countries your company has enabled in Fluid, and a picker in the header lets shoppers switch. It chooses a shopper’s locale the same way a Fluid-hosted storefront does: the lang and country query parameters, then the locale cookie, then the browser’s language and the shopper’s country, then your company’s default. Prices, currencies, and product availability follow the country. Content follows the language. The SDK and checkout read the same cookie, so the cart and checkout stay in the shopper’s language and country. See Translate storefront resources and Country availability.

SEO

Every page gets a title, meta description, canonical URL, Open Graph and Twitter tags, and hreflang alternates, from each resource’s seo settings in Fluid. A resource Fluid marks as not indexable gets a noindex tag. Products, posts, and the site carry schema.org structured data, and the app serves /sitemap.xml and robots.txt. See SEO for storefront resources.

Cart and checkout

The starter loads the FairShare SDK on every page, the same bundle Fluid-hosted themes use. Shoppers add to the cart with Fluid’s cart drawer, and Checkout hands the cart to Fluid’s hosted checkout. To build your own cart UI, use the React hooks in src/lib/fairshare/hooks.ts. See the FairShare SDK for every cart method.

Keep pages fresh

The app caches Fluid’s responses for FLUID_REVALIDATE_SECONDS. To refresh sooner, send a POST to /api/revalidate on your storefront with an Authorization: Bearer header carrying your REVALIDATE_SECRET. To refresh whenever something changes in Fluid, point a webhook at it.

What the public API doesn’t provide

A headless storefront sees only what the public storefront API returns. Plan for these gaps:
  • Page content. A page returns its title, description, image, and metafields, but not the content built in Fluid’s page editor. Build page content in a template. Metafields are a good home for copy merchants should be able to edit. See Metafields.
  • Redirects. Redirects set up in Fluid Admin don’t apply. Add them to next.config.ts.
  • Navigation menus. Your Fluid website navigation menus need FLUID_COMPANY_PRIVATE_TOKEN. Without it, the starter uses the links in src/config/site.ts.
  • Tag manager and analytics. Add your tags to the app’s layout yourself.
  • Theme template choice. The template a merchant assigns in Fluid Admin isn’t returned, which is why templates match by slug.