For example, use a section for an announcement or review panel, a body embed for a floating widget, and a head embed for global scripts or styles.
Before you upload
The upload workflow requires the feature-gated Theme Extension card to be available in your environment. Contact Fluid if you do not see it.
- Create a Droplet, or open one owned by your company. See Creating Droplets.
- Have a Fluid administrator enable
DROPLET_THEME_EXTENSIONSfor the Droplet owner company. This flag is off by default and exposes the Theme Extension upload card on Droplet create/edit forms. - Install the Droplet in the company whose storefront will use the extension. An active installation is required, including when the owner company tests its own Droplet.
Package structure
Putfluid.extension.toml at the ZIP root:
type and name are required. theme is the supported type; version is informational.
Create the ZIP from inside the extension directory so the manifest is at its root:
Create a page section
Createsections/announcement/index.liquid:
section.settings. After installation, a merchant can add the section through Add Section → Apps, edit its settings, and save or publish the page.
Create an app embed
Createsections/floating_widget/index.liquid:
block.settings, even though their files live under sections/. The renderer merges schema defaults with saved embed settings.
target: "body"adds the rendered content tocontent_for_layout, which your layout outputs inside the body.target: "head"adds the rendered content tocontent_for_header, which your layout outputs inside the head. Use head-compatible content, such as scripts or styles, for this target.
Upload and publish the extension
- Open Droplets and create or edit your Droplet.
- In Theme Extension, choose Upload Extension Zip and select one ZIP.
- Save the Droplet. The extension is imported in the background.
- Check the Droplet’s extension status. Wait for Published before testing it in the theme editor. If it reports Error, inspect the import error on the Droplet detail page.
Use extension sections in the builder
Add a section to a page
- Install the Droplet in the company whose storefront you are editing. Confirm that its theme extension is published.
- Open the page or theme template in the visual builder.
- Click Widgets (the puzzle-piece icon) in the left sidebar. Installed Droplets’ sections are listed under each Droplet’s name, below its embed toggles.
- Drag the section to the desired position. For the example above, drag Announcement. You can also click Add Section in the canvas and select Apps; that tab appears when installed extensions provide eligible page sections.
- Select the new section in the canvas or Layers. Edit its settings in the sidebar, such as Heading and Message.
- Use the builder to reorder or remove the placement as you would another page section.
- Save your changes and use the page’s normal publish workflow. Check the storefront page using that template.
Add an app block inside a section
A host section must declare{ "type": "@app" } in its schema’s blocks list before the builder offers installed app blocks.
- Select a section that supports app blocks.
- Click Add Block and choose the extension block from the app choices.
- Select the block in Layers and edit its settings in the sidebar.
- Save and publish the page through its normal workflow.
@app, and {% render block %} renders its extension content with block.settings.
Enable an app embed in the builder
- Install the Droplet in the storefront company and confirm its extension is published.
- Open the theme editor for the theme you want to configure.
- Click Widgets (the puzzle-piece icon) in the left sidebar.
- Find your embed under Head or Body, then turn it on. The toggle saves the configuration for that theme.
- Open or reload a storefront page to check the result. Turn the toggle off to stop including the embed.
Add extension content without the builder UI
Use these file-based recipes when editing a theme directly or giving an AI agent a theme task. The Droplet must still be actively installed in the storefront company and its extension must be published. Editing a template does not install a Droplet.Obtain the real extension URI
Extension templates use this identifier format:extension_uri metadata, or the extension developer. The identifier after extensions/ is the theme extension ID, not the Droplet ID, installation ID, or theme ID. The final segment is the template’s directory name, without /index.liquid.
The examples below assume an installed extension with ID 42 and the templates from this guide. Replace each example URI with the real URI for your environment. If an agent cannot obtain it, have the agent request it before editing; do not guess an ID or substitute a plain section name.
Place a page section directly in Liquid
For a section withtarget: "section" (or no target), add a literal section tag at the desired position in the page template, such as home_page/default/index.liquid. Add the matching instance to that page’s existing schema:
{% schema %} block.
The tag’s id and the key in sections must match. Keep the full extension URI in both the tag and the instance’s type. Give each placement a unique ID, and keep that ID stable when updating its settings. The tag’s position in the Liquid determines where the section renders.
The section reads this instance’s values from section.settings. Use setting IDs declared by the extension’s schema. Two placements of the same extension section can use the same URI and different instance IDs and settings.
Keep the page as a Liquid template with embedded schema JSON. Upload or push the changed theme files through your normal theme development workflow, then save/publish the intended template and verify it on the storefront. A local file edit alone does not update the live site.
Enable a global embed through theme configuration
Fortarget: "head" or target: "body", edit the storefront company’s theme file config/settings_data.json. This is the file-based equivalent of enabling the embed in Widgets; do not place this widget using the page-section recipe above, which supplies section.settings rather than the embed’s block.settings.
If current is an object, merge an entry into current.blocks:
current is a preset name such as "Default", leave that string in place and edit the active preset’s blocks instead:
false to enable the entry and true to disable it. Saved settings override the embed schema defaults and are available as block.settings. The extension template’s schema chooses head or body placement; adding a target field to this configuration does not change that placement.
Your layout must output {{ content_for_header }} inside its head and {{ content_for_layout }} inside its body. Preserve those outputs in custom layouts so enabled embeds can appear. Publish/synchronize the changed theme configuration through your normal theme workflow and verify a storefront page using that theme.
Instructions for AI agents
For Mist or another agent building a section that reads private member data, follow the backend-and-section workflow alongside this placement recipe. Provide the agent with the target company/theme, the page template if placing a section, the exact extension URI, the extension schema, and the requested settings. Use this task brief:Call your backend from extension scripts
An extension’s Liquid renders the shell of a feature. For live data, its JavaScript calls your Droplet’s own backend. That call runs in the visitor’s browser on the merchant’s storefront, which is a different origin from your backend, so the browser treats it as a cross-origin request.- Allow the storefront origins. Send CORS headers that allow each storefront origin that uses the extension: the company’s
fluid.appsubdomain and any custom domain. Answer the browser’sOPTIONSpreflight request too. Without it, requests that send JSON or custom headers fail before they reach your handler. - Treat every request as public. Liquid output and extension assets reach every visitor, and storefront pages are shared between visitors. Never put API tokens, the Droplet’s webhook secret, or other credentials in them.
- Check identity on your server. A customer or member ID that your script sends can be changed by anyone. Don’t return private data on the strength of it. On member pages, use the Droplet data connection, which sends Fluid-signed member and company context to your backend.
- Rate-limit writes. Anyone who can load the page can call an endpoint that creates or changes data, such as a review or a sign-up. Limit how often each visitor can call it, and validate every input on the server.
Troubleshooting
The ZIP limit is 50 MB. Keep the archive focused on your extension files.