Skip to main content

When a Fillo form misbehaves.

The five failure modes we actually see — symptom, cause, fix — plus the JSX authoring error catalog. Ninety seconds, tops.

Setup lives at /docs/embed, the styling contract at /docs/styling.

On this page

The form renders unstyled under Tailwind v3

Symptom
The form works but looks bare — no borders, spacing, or button styling.
Cause
@usefillo/react/styles.css ships its rules in @layer components. Any unlayered CSS — Tailwind v3’s preflight, most resets — outranks every layered rule, so the default theme silently evaporates.
Fix
Import @usefillo/react/styles.unlayered.css instead. Details in the stylesheet matrix.

The hosted /f page doesn't match my embed

Symptom
appearance.classNames styling shows in your app but not on the hosted page or dashboard preview.
Cause
By design — classNames never sync; the hosted page renders the default renderer plus theme tokens only.
Fix
Put brand parity in theme tokens (defineForm({ theme }) or the dashboard theme); keep classNames for embed-only polish.

The form says “This form isn’t live yet” or eats submissions

Symptom
A code-defined form renders, but shows “This form isn’t live yet” in production (or a draft banner in dev) and refuses responses.
Cause
Code forms sync as drafts; the server rejects public submissions until a human publishes.
Fix
Publish the form in the dashboard — the browser console notice links straight to it. Staged schema changes need the same publish step.

Submit fails with “Couldn’t reach the server”

Symptom
The form fails to load or submit with a network error while the rest of the site is fine.
Cause
An ad-blocker, corporate firewall, or your site's Content-Security-Policy is blocking requests to fillo.so.
Fix
Check the browser network tab for the blocked request. If your site sets a CSP, allow connect-src https://fillo.so. For ad-blockers and VPNs, retry with them off to confirm.

Blank form, or “useFillo must be used inside…”

Symptom
The form renders nothing, or a component that is clearly inside the provider throws useFillo must be used inside <FilloForm> or <FilloProvider>.
Cause
Two copies of @usefillo/react (or of React itself) in the bundle — context identity differs across copies.
Fix
Dedupe to a single copy: npm dedupe / one version in the lockfile; in monorepos check hoisting and bundler aliases.

JSX authoring errors

Mistakes in <Fillo.Form> authoring throw FilloJsxError with a stable code; the error message links straight to its entry below. The authoring guide lives at /docs/authoring.

jsx-missing_id

A block, an <Fillo.Option>, or <Fillo.Form> itself has no stable string id (1–128 chars); options also need a label.

Fix: Write a permanent id by hand — ids key responses, logic, piping, and sync, so never derive them from position or a counter.

jsx-duplicate_id

Two blocks share one id. Ids key responses and must be unique across the whole form, pages included.

Fix: Rename one. If the form is live, keep the id existing responses were stored under and rename the newcomer.

jsx-non_fillo_child

Something that isn't a Fillo element sits where the schema expects one — raw text or HTML inside <Fillo.Form>, children on a props-only field, or <Fillo.Option> outside a choice field.

Fix: Children define the schema: put text in <Fillo.Paragraph>, layout outside the form (or go headless with FilloProvider), and options inside Select, MultiSelect, Dropdown, or Ranking.

jsx-wrapper_component

A plain React component was used as a form child. The compiler never renders children, so wrappers are invisible to it.

Fix: Reuse via a plain function that returns Fillo elements and call it inline: {contactFields()}.

jsx-opaque_type

A child's component type is opaque — lazy/memo, or the JSX crossed a server-component boundary and arrived as a reference.

Fix: Define the form in a client module ("use client") and pass the compiled value across server/client boundaries, never the JSX.

jsx-unknown_prop

A prop isn't in that component's schema whitelist. Typos and className/style land here instead of vanishing silently.

Fix: Use the props in the component reference; styling lives on <Fillo.Form appearance={…}>, never in the schema.

jsx-option_prop_conflict

A choice field has both an options prop and <Fillo.Option> children, or a heading/paragraph has both a text prop and children.

Fix: Pick one source — both compile identically.

jsx-page_mix

<Fillo.Form> mixes <Fillo.Page> elements with loose blocks, or a Page/Option appears inside a page.

Fix: Children are either all pages or all blocks — wrap the loose blocks in a <Fillo.Page>.

jsx-text_child_required

A Heading or Paragraph has non-string children (expressions, elements), or no text at all.

Fix: Pass plain text as children or the text prop — piping tokens like {{name}} are fine.

jsx-rendered_inert

React actually rendered a Fillo.* field — it was used outside <Fillo.Form> / Fillo.defineForm(), often from a server component.

Fix: Keep fields inside <Fillo.Form>, and define the form in a client module ("use client").

Was this page useful?

Was this page helpful?
Powered by Fillo