Skip to main content
A Droplet theme extension packages Liquid templates that render inside a company’s storefront theme. Use sections for content merchants place on individual pages, and app embeds for features they enable across the storefront. Droplet app embeds are included on standard storefront pages; they are not injected into member-site pages. Sections and app blocks can be placed on member pages too, where they act as member storefront widgets. See Droplet widgets. 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.
  1. Create a Droplet, or open one owned by your company. See Creating Droplets.
  2. Have a Fluid administrator enable DROPLET_THEME_EXTENSIONS for the Droplet owner company. This flag is off by default and exposes the Theme Extension upload card on Droplet create/edit forms.
  3. 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.
The flag controls the upload UI. Installing the Droplet makes its published templates available, and the Widgets panel toggles control which embeds appear in a theme.

Package structure

Put fluid.extension.toml at the ZIP root:
The manifest declares the extension type and display name:
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:
Include any additional directories you use in the same archive. A complete theme layout or page template is not required.

Create a page section

Create sections/announcement/index.liquid:
Page sections read settings from 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

Create sections/floating_widget/index.liquid:
App embeds read settings from block.settings, even though their files live under sections/. The renderer merges schema defaults with saved embed settings.
  • target: "body" adds the rendered content to content_for_layout, which your layout outputs inside the body.
  • target: "head" adds the rendered content to content_for_header, which your layout outputs inside the head. Use head-compatible content, such as scripts or styles, for this target.
The Widgets panel provides enable/disable toggles for embeds. It does not expose a settings editor, so give embeds useful schema defaults.

Upload and publish the extension

  1. Open Droplets and create or edit your Droplet.
  2. In Theme Extension, choose Upload Extension Zip and select one ZIP.
  3. Save the Droplet. The extension is imported in the background.
  4. 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.
Cancel extension upload discards the pending selection before saving. It does not delete a published extension. Disabling the feature flag while editing also discards any pending selection. To publish an update, upload a new ZIP and save again. Import replaces the extension’s templates and assets; the package must contain everything you want to keep. There is one theme extension per Droplet, and installed companies use the latest published version rather than selecting a version independently.

Use extension sections in the builder

Add a section to a page

  1. Install the Droplet in the company whose storefront you are editing. Confirm that its theme extension is published.
  2. Open the page or theme template in the visual builder.
  3. Click Widgets (the puzzle-piece icon) in the left sidebar. Installed Droplets’ sections are listed under each Droplet’s name, below its embed toggles.
  4. 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.
  5. Select the new section in the canvas or Layers. Edit its settings in the sidebar, such as Heading and Message.
  6. Use the builder to reorder or remove the placement as you would another page section.
  7. Save your changes and use the page’s normal publish workflow. Check the storefront page using that template.
Each placement has its own settings. Removing a placement removes that instance from the page; it does not uninstall the Droplet or delete its extension. Edit your page’s placement settings, rather than copying the extension’s Liquid into a theme-owned section. Head/body embeds cannot be placed as sections. Turn them on in the Widgets panel instead.

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.
  1. Select a section that supports app blocks.
  2. Click Add Block and choose the extension block from the app choices.
  3. Select the block in Layers and edit its settings in the sidebar.
  4. Save and publish the page through its normal workflow.
If you author the host section, preserve its existing block handling and add an app-block branch to its Liquid loop:
The builder saves a specific extension URI for the selected block. At render time, that block is exposed to the host as @app, and {% render block %} renders its extension content with block.settings.

Enable an app embed in the builder

  1. Install the Droplet in the storefront company and confirm its extension is published.
  2. Open the theme editor for the theme you want to configure.
  3. Click Widgets (the puzzle-piece icon) in the left sidebar.
  4. Find your embed under Head or Body, then turn it on. The toggle saves the configuration for that theme.
  5. Open or reload a storefront page to check the result. Turn the toggle off to stop including the embed.
Embeds start disabled. Enabling one applies it site-wide within that theme; it does not add a draggable section to a page. Page sections are placed separately, by dragging them from the same panel or through Add Section → Apps.

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:
Use the exact URI from an existing saved placement, the extension template’s 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 with target: "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:
This is a minimal page fragment. Merge it into the existing Liquid and schema; do not replace the rest of the page or append a second {% 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

For target: "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:
This example shows only the relevant configuration. Preserve all unrelated theme settings, blocks, and presets. If the embed already exists, update that entry instead of adding a duplicate. Keep its existing block key. If current is a preset name such as "Default", leave that string in place and edit the active preset’s blocks instead:
Use the boolean 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.app subdomain and any custom domain. Answer the browser’s OPTIONS preflight 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.