Conversation
…elements
When rendering entry HTML via render_entry_with_templates / render_entry_template_with_locator, root custom elements receive the full root state directly. Any attribute whose value is a pure {{expr}} double-brace binding was only needed to forward state via the attribute-based child state mechanism — with entry-level rendering that mechanism is bypassed, so these attributes are now stripped from the rendered HTML output.
Examples stripped: list="{{list}}", item_parent="{{item_parent}}", someData="{{someData}}"
Static attributes (id, class, disabled, etc.) are preserved.
Changes:
- attribute.rs: add is_state_passing_binding() and strip_entry_attrs() (strips client-only attrs + {{binding}} attrs)
- directive.rs: build_element_open_tag gains is_entry param; uses strip_entry_attrs when true
- wasm.rs: expose render_entry_with_templates WASM binding
- fast.js CLI: use render_entry_with_templates when templates are provided
- tests/custom_elements.rs: 4 new tests for entry-level attr stripping behaviour
- Regenerate attribute, binding, event fixture index.html files
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…s-on-root-elements
…ents; strip non-primitives
For entry-level root custom elements, {{binding}} attribute values are now resolved
from root state:
- Primitive (string/number/bool): rendered with resolved value, e.g. text="{{msg}}" → text="Hello world"
- Non-primitive (array/object/null): stripped — cannot be an HTML attribute value
Static attributes (no binding syntax) are passed through unchanged.
This is implemented via build_entry_element_open_tag in directive.rs which replaces
the earlier strip_entry_attrs approach. HTML escaping is applied to string values.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…s-on-root-elements
There was a problem hiding this comment.
Pull request overview
This PR updates @microsoft/fast-build entry-level rendering so that root custom elements no longer emit noisy “state-passing” {{binding}} attributes in the rendered HTML, and exposes the entry-level renderer via WASM for the CLI to use when templates are provided.
Changes:
- Add entry-level opening-tag handling for root custom elements (resolve primitive
{{...}}attrs, strip non-primitives). - Expose
render_entry_with_templatesas a WASM binding and switch thefast-buildCLI to use it when templates are present. - Add integration tests and documentation updates describing the entry-level attribute behavior.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/fast-build/bin/fast.js | Switch CLI rendering path to entry-level semantics when templates are provided. |
| crates/microsoft-fast-build/src/wasm.rs | Export render_entry_with_templates for WASM consumers. |
| crates/microsoft-fast-build/src/directive.rs | Implement entry-level root custom element opening-tag attribute handling. |
| crates/microsoft-fast-build/tests/custom_elements.rs | Add integration tests for entry-level root custom element attribute behavior. |
| crates/microsoft-fast-build/README.md | Document entry-level root element attribute handling semantics. |
| crates/microsoft-fast-build/DESIGN.md | Update design notes to reflect new entry-level opening-tag behavior. |
| change/@microsoft-fast-html-f43a3bf8-58f2-4224-a8b1-d248b5f47b7e.json | Record fixture regen for @microsoft/fast-html. |
| change/@microsoft-fast-build-strip-entry-binding-attrs.json | Record minor feature change for @microsoft/fast-build. |
- Use strip_client_only_attrs as first step in build_entry_element_open_tag
to avoid duplicating the client-only attr filter list
- Handle ?attr="{{expr}}" boolean attribute bindings: evaluate as boolean,
emit bare attr name (without ?) when truthy, omit when falsy
- Fix wasm.rs doc comment for render_entry_with_templates to accurately
describe primitive-kept / non-primitive-stripped behavior
- Add tests: test_root_custom_element_boolean_attr_binding_truthy and _falsy
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
janechu
added a commit
that referenced
this pull request
Apr 8, 2026
Regenerate repeat/index.html after rebasing onto main (which includes PR #7403 entry-attribute stripping and PR #7380 when fixture). Changes reflect correct entry-element behavior: - Non-primitive binding attrs (list, someData) stripped from opening tag - test-element-no-item-repeat-binding now renders empty repeat since list="{{emptyList}}" overrides root list with [] in merged state Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
janechu
added a commit
that referenced
this pull request
Apr 8, 2026
Regenerate repeat-event/index.html after rebasing onto main (which includes #7381 repeat fixture, #7380 when fixture, and #7403 entry-attribute stripping). Non-primitive binding attrs (items) are now stripped from entry element opening tags; primitive attrs (show-names="true") are preserved. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request
📖 Description
When rendering the top-level entry HTML via
render_entry_with_templates/render_entry_template_with_locator, root custom elements receive the full root state directly. Before this change, any{{binding}}attribute on a root element was resolved and written into the rendered HTML as-is — e.g.list="{{items}}"becamelist="[Array]". These noisy rendered values are now handled correctly:string,number,boolean) — resolved and rendered. e.g.text="{{message}}"→text="Hello world".array,object,null) — stripped. State is available directly in the template via entry-level rendering.?attr="{{expr}}"boolean bindings — evaluated as a boolean; bare attribute name emitted when truthy, omitted when falsy.id="main",disabled, etc.) — passed through unchanged.Additionally,
render_entry_with_templatesis now exposed as a WASM binding and the CLI updated to use it. The implementation usesstrip_client_only_attrsas a first pass to avoid duplicating the client-only attr filter list.📑 Test Plan
?attrtruthy/falsynpm run build:fixturesregenerates correctly —attribute,binding,eventfixtures match expected output✅ Checklist
General
$ npm run change