How to build a custom widget

Build your own reusable widgets with HTML, CSS and JavaScript, or describe one and let Zeus build it. Publish it and it shows up in the editor's Add panel on every one of your sites.

Updated October 15, 2026

A custom widget is a building block you design once, like a pricing table, a team carousel or a scrolling logo strip. Anyone editing one of your agency's sites can drop it onto a page and fill in their own content, like any other widget. Use it when the built-in widgets don't do what you need and you'll want the same thing on more than one site.

Build it once, reuse it everywhere

Everything a site owner would change is a content field: text, headings, images, logos, links, buttons and repeated items. The HTML only places those fields. Repeated items, such as the logos in a logo strip, are one List (repeater) field, so site owners add, remove and reorder them. Visual choices, such as colors, sizes, gaps, scroll speed, direction and pause on hover, are design fields.

A newly dropped widget shows a demo built from the fields' default values, such as six gray placeholder logos. It never comes from text written into the HTML.

How to start a widget

  1. Open Custom Assets in the sidebar and click Widget Builder.
  2. Click New widget, type a Name (for example "Team Carousel") and click Create.
  3. The builder opens. Your work saves automatically as you go ("All changes saved").

The library page has two parts:

  • Your agency's widgets: the ones you build. Each card shows a status: Draft only (never published), Published v3 (the version sites use), or Published v3 · unpublished changes (you've edited it since the last publish). Buttons: Open (or View if you can't edit it), Duplicate and the bin icon to delete.
  • ContentForge library: shared widgets every agency can use. You can view and duplicate them but not edit them. In a white-label account the editor calls these Library widgets.

Bring in a widget you already have

Next to New widget is the import button, for widgets built in another site builder. Give it a Name, paste its HTML, CSS and JavaScript, and click Import. Its templates and config calls work as they are. The content fields are detected from the code, so check them afterwards.

How to build it by hand

The builder has tabs on the left and a live preview on the right. At the top you set the widget's icon, its name and the short description shown in the Add panel.

  • HTML: the template. Put a field in it with double braces, for example {{title}}. Loop over a list field with {{#each logos}}…{{/each}}. The HTML is rendered into the page, so search engines see it.
  • CSS: scoped to the widget automatically, so it can't restyle the rest of the site. Every design field is available as a CSS variable.
  • JavaScript: runs on the live page. Read field values from the widget's config.
  • Content fields: what site owners fill in after dropping the widget on a page. Detect fields from code adds a field for every variable it finds that doesn't have one yet.
  • Design fields: style settings that show in the widget's Design panel. Each one becomes a CSS variable.
  • Settings: Run the JavaScript in the site editor too. Turn that off for scripts only needed on the live site, such as analytics or heavy effects. The editor then shows just the HTML and CSS.
  • Help: the template and code reference.

Field types

Each field has a Key (used in the code) (letters, numbers and _ only, can't start with a number, unique), a label, optional Help text and Placeholder, and a Default value. The types are:

  • Text: one line. Paragraph: several lines of plain text. Rich text: bold, links and lists.
  • Number / slider: a number with optional min, max and unit.
  • Toggle: on or off. Dropdown: one of a list of options. Color: a color, theme colors included.
  • Image: an uploaded image with alt text. Video: a video link or upload.
  • Link: a link to a page, URL, phone, email, popup and so on.
  • Date & time: a date, optionally with a time.
  • List (repeater): items that each have their own fields (no lists inside lists). Name what one item is called, such as "slide" or "card".
  • Collection: rows from one of the site's collections.
  • Heading: a label to group fields in the panel (holds no value).

Number, Toggle, Dropdown, Color and Heading can also be design fields.

The preview

The preview switches between Desktop, tablet and phone widths. It has a Run JS toggle and Reload.

Under the preview, Try it shows the widget's Content window and Design panel exactly as site owners get them. Change anything there to see the preview update: add or remove list items, upload images, or change design settings. Only the preview uses these values. Reset to defaults puts the defaults back.

The reusable check

Above the preview, the builder checks that the widget takes its content from fields. Not reusable yet: 3 things written into the code lists what's wrong, such as:

  • an image or logo written into the HTML or CSS instead of an image field;
  • a link written into the HTML instead of a link field;
  • three or more repeated items written out one by one instead of a List field;
  • a sentence or heading written into the HTML;
  • a field the HTML uses that doesn't exist, or a field nothing uses;
  • a hard-coded list or image address in the JavaScript.

Softer issues show as Reusable, 2 things worth a look, for example a short phrase in the HTML, fixed alt text, or a list that starts empty.

Click Make it reusable and Zeus moves that content into fields. Today's content becomes the defaults, so the widget looks the same.

How to let Zeus build it

  1. Click Ask Zeus.
  2. Describe the widget (or, on an existing widget, what should change) and click Build it (or Make the change). The credit cost shows on the button.
  3. Zeus works through stages such as "Reading your request…", "Designing the layout…", "Writing the HTML and CSS…" and "Checking the code…". A big widget can take a few minutes. Keep the panel open.
  4. Zeus shows a proposal with a preview, what site owners will fill in, and anything still worth a look. Click Apply to use it, or ask for a different change.
  5. Changed your mind after applying? Click Undo Zeus change at the top.

Zeus checks his first version and, if anything is written into the code, makes it again before showing you. When you ask for a change, such as "make the logos bigger", Zeus keeps the fields and their keys, so content already filled in on sites stays. Make it reusable instead in the same panel converts a widget that has content written into its code.

Click Stop to cancel while he works. You'll see "Stopped. Your credit went back."

How to save and publish

Your work saves automatically. Click Publish to make the current version the one sites use. Each publish raises the version number (v1, v2…). The editor picks up the new version right away. Live sites get it the next time they're published.

Examples

  • A logo strip for every client: a List field "Logos" (Image + Link per item), design fields for speed, gap and pause on hover. Each client fills in their own logos.
  • A price calculator: Number fields for the rates, a Dropdown for the service, JavaScript that does the sum. Turn off running the script in the editor if it's heavy.
  • Zeus build: "A team carousel with photo, name, role and a LinkedIn link per person, three across on desktop, one on phone." Zeus makes the List field and placeholder people.
  • Bring in old work: paste a widget from your old site builder with the import button, then click Make it reusable to move anything hard-coded into fields.

Limits and what it can't do

  • HTML, CSS and JavaScript together can be up to 400 KB.
  • Lists can't contain other lists.
  • A Zeus request gets up to 3 tries to finish. If he keeps stopping, the request fails and the credit goes back.
  • Widgets in the ContentForge library can't be edited, only duplicated.
  • A widget is shared by all your agency's sites. You can't limit one to a single client.
  • Deleting a widget removes it from the library and the Add panel. Pages that use it show a warning in the editor. Live sites keep showing it until they're published again.
  • Client people never see the Widget Builder.

Credits

Each Zeus request (build, change or Make it reusable) costs credits per run, shown on the button and at the top of this page. Writing code by hand, Detect fields from code, the reusable check, previewing and publishing are free. If Zeus stops, fails or returns nothing, the credit goes back.

Who can use it

  • Anyone with the Mount Olympus tool sees Custom Assets → Widget Builder and can open widgets view-only.
  • Agency Owners and Admins can create, import, change, duplicate, publish, delete and use Ask Zeus. Others see "Only agency owners and admins can build widgets. You can view the widgets available to your sites."
  • Client people can use published widgets on their own site (see Use custom widgets on a site) but can't open the builder.

Troubleshooting

  • "Only agency owners and admins can build widgets": your role is Member or similar. Ask an owner or admin to change your role, or to build it.
  • "Name the widget": the name box is empty. Type a name and click Create.
  • "The widget code is too large (400 KB max)": move images out of the code into image fields, and trim unused CSS or scripts.
  • "The HTML template has an error: …" when you click Publish: a {{#each}} or {{#if}} isn't closed, or a brace is mistyped. Fix the line named in the message.
  • "Could not save — check your connection": your last change didn't save. Check your internet connection and make another small change so it saves again.
  • "Zeus didn't return a widget — try again" or "Zeus is unavailable right now — try again": nothing was charged (the credit went back). Try again in a minute.
  • "The widget was too long to finish — ask for something smaller or in steps": ask for the basic widget first, then add features one change at a time.
  • "Zeus kept stopping before the widget was finished. Your credit went back — try again, or ask for something smaller.": the 3 tries ran out. Make the request simpler.
  • "… needs 1 credit — you have 0. Buy credits to continue.": top up from the Buy credits button.
  • Every site shows the same logos or text: that content is written into the HTML. Click Make it reusable, then publish.
  • Sites still show the old version: click Publish in the builder (the card should no longer say "unpublished changes"), then republish each live site.

Didn't find what you need?

Send us a message — no sign-in needed — or email support@the-contentforge.com. Already a customer? Sign in to submit a ticket.

Contact support