Skip to main content
A member site is its own small theme. Its pages are Liquid templates that read only the site’s own files. This page covers what a site holds, the Liquid objects its templates can read, and the rules of the frame it renders in. To read a member’s data, use a script instead: see Read viewer data in site scripts.
Member sites are not storefront themes. A site can’t use a theme’s files, settings or stylesheets, and fluid theme commands don’t touch it. See the overview.

Know the folder

A site holds six kinds of file. In the CLI, each lives in a folder of the same name, and a path in the folder is the path the file API uses.
  • No subfolders. A name uses lowercase letters, digits, hyphens and underscores. Names that start with a dot are ignored.
  • A page is a file and a row. pages/<slug>.liquid holds the content, and a row in config/pages.json holds the slug, title, position, published flag, layout and menu. A new page needs both. A site holds at most 50 pages.
  • The home page’s slug is / in config/pages.json, and its file is pages/index.liquid. A slug is never index.
The CLI page shows the folder, and Pages and menus explains the config files.

Pick a layout

A page uses its row’s layout, else the site’s default layout, else layouts/site.liquid. The layout name none renders the page with no layout. A missing layout falls back to site: see Pages and menus. A layout prints the page where it writes content_for_layout, and Fluid’s head content where it writes content_for_header:
layouts/site.liquid
content_for_header carries what the page needs in its <head>: the site SDK that installs window.fluid, and a link to assets/site.css when the site has that file. A page with no layout can print content_for_header too.

Read the Liquid objects

A page and its layout render with the same objects.
  • Every url is a path on your company’s domain, such as /accounts/rileys-shop/about. Use it as written in links.
  • An unpublished page isn’t listed. A page with published: false isn’t in site.pages, site.pages_menu or any menu.
  • Don’t read member data in Liquid. Don’t read member or member.<field> in a layout, section, snippet or page. Member data is leaving member site Liquid, and fluid member-site lint warns on every member.<field> it finds. Read the viewer’s data in a script.
  • Keep members’ data out of settings. config/settings.json is the same for every viewer.
A navigation snippet reads settings.menu:
snippets/nav.liquid

Use tags and filters

A site’s Liquid reaches its own files only. A page template can use a section, a snippet and a settings value together:
pages/index.liquid
Sections can carry a {% schema %} block. Lint checks it, and the pairing of block tags such as {% if %} and {% endif %}.
Load a site’s JavaScript with script_tag, or add crossorigin="anonymous" to a hand-written <script src>. Fluid serves a site’s script only to a request from the site’s own frame, which sends Origin: null. A plain <script src> sends no origin, and Fluid answers it with 404. A <script> element with the code inline works either way.

Know the frame’s rules

Every page renders in an iframe on your company’s domain with this policy:
The sandbox never allows the same origin, so the page has an opaque origin. Your code runs freely inside it. These rules follow:
  • No cookies and no storage. A site’s JavaScript has no cookie, and reading document.cookie throws. It has no localStorage or sessionStorage. Don’t build sign-in, “remember me” or any state that relies on them, and never put a token or other credential in Liquid, settings or an asset.
  • Scripts and forms only. The sandbox grants scripts and forms. The browser also blocks popups, alert and confirm dialogs, and navigation of the top page.
  • Fluid draws the account menu. It appears outside the frame on every page, even a page with the layout none. No template can hide or replace it, so don’t build a second account menu or a sign-out link.
  • Link inside the site. Use site.pages and menu url values. A click navigates inside the frame.
  • Reach Fluid with fluid.fetch. The frame has no cookie, so the page’s own fetch to a Fluid API carries no session and fails. Call window.fluid.fetch(path, init) instead, which behaves like fetch. See Read viewer data in site scripts.

Use text assets only

A site holds text assets only: css, js, json, txt and html files in assets/, valid UTF-8 and not empty. A push refuses any other file. Don’t put an image, a font, a PDF or a video in the folder, and don’t inline one as a large base64 string. Upload images and fonts to your company’s media library and use the URL it gives you, in an <img src>, in background-image: url(...) and in an @font-face src.
assets/site.css
An asset has no draft. A new, changed or removed asset is live on a published site as soon as a push writes it, so write assets that still work with the published pages. See Know what is live at once.

Preview and publish

Page content, layouts, sections, snippets and settings are drafts until you publish the site, and members see only the published copies. See Publish a site. To see a draft, run fluid member-site dev, or use the draft preview operations of the member API or the company API.