Skip to content

Linter Rule: Validate component structure and attributes in slots templates

Rule: herb-slots-valid-components

Description

Validates the built-in component tags in a template that declares herb:slots. A <Fragment> needs exactly one <Fallback>, a <Fallback> belongs directly inside a component, attributes must be ones the component takes, timing attributes take whole milliseconds, and a deferred block cannot sit inside a collection.

Rationale

The engine's slots visitor reports these same problems as compile diagnostics, so they surface in the dev tools once the page runs. This rule reports them in the editor, using the same messages, before the page runs at all, the same arrangement herb-state-valid-actions has with the runtime.

The checks mirror the engine. <Fragment> takes delay, hold and on, the deferred blocks <Async> and <Lazy> take delay, hold and poll, and <Fallback> takes no attributes yet. A <Fallback> counts only as a direct child of its component, a <Fragment> cannot sit directly inside a <Fallback>, and an unknown capitalized name is reported the way the engine reports it. One engine warning stays engine-only, the one saying a fallback can never appear, since deciding it needs the server-read analysis only the compiler has.

Templates without a herb:slots directive are left to herb-component-requires-slots.

Examples

✅ Good

erb
<%# herb:slots client %>

<Fragment delay="0" hold="600">
  <p><%= Geo.locate(city) %></p>
  <Fallback><p class="pulse">Looking it up</p></Fallback>
</Fragment>

🚫 Bad

erb
<%# herb:slots client %>

<Fragment delay="fast" id="card">
A `<Fragment>` holds 2 `<Fallback>` elements, and it can only stand one in. (herb-slots-valid-components)
`delay` on a `<Fragment>` takes a whole number of milliseconds. (herb-slots-valid-components)
`<Fragment>` only takes `delay` and `hold` and `on`. (herb-slots-valid-components)
<p><%= Geo.locate(city) %></p> <Fallback class="pulse"><p>Looking it up</p></Fallback>
`<Fallback>` takes no attributes yet. (herb-slots-valid-components)
<Fallback><p>Still looking</p></Fallback> </Fragment>

References

Released under the MIT License.