Skip to content

Conversation

@willrowe
Copy link
Contributor

@willrowe willrowe commented Mar 17, 2025

This adds an ignore-nullish modifier to x-html and x-text. If the value is set to null or undefined, the currently set HTML/text will remain unchanged.

The main use case for this is to have the initial HTML/text set in the markup on page load. See the updates to the documentation for examples.

@ekwoka
Copy link
Contributor

ekwoka commented Mar 18, 2025

I like the modifier approach.

I think I'd be more partial to preserve-nullish as opposed to ignore but that's just my opinion.

@willrowe
Copy link
Contributor Author

willrowe commented Mar 18, 2025

@ekwoka

I think I'd be more partial to preserve-nullish as opposed to ignore but that's just my opinion.

preserve-nullish implies that you are preserving a nullish value, which I would find confusing.

@ekwoka
Copy link
Contributor

ekwoka commented Mar 18, 2025

Yeah....but preserve-on-nullish is too long 😭

@Tim-Wils
Copy link

What is the value becomes null again after being set to a value? Shouldn't the value become the original innerHTML again with this modifier?

@willrowe
Copy link
Contributor Author

@Tim-Wils no, as the name infers, it ignores any nullish values and does not change the HTML/text. It will be most useful on initial state.

@calebporzio
Copy link
Collaborator

PR Review: #4579 — Add ignore-nullish modifier to x-html and x-text

Type: Feature
Verdict: Needs discussion

What's happening (plain English)

This PR adds a new .ignore-nullish modifier to x-text and x-html. The idea:

  1. You have server-rendered HTML like <h1 x-text.ignore-nullish="title">Loading...</h1>
  2. Your data starts as null — maybe it hasn't loaded from an API yet
  3. Without the modifier, Alpine immediately sets the text to null (the string), wiping your placeholder
  4. With .ignore-nullish, Alpine skips the update when the value is null or undefined, preserving whatever text/HTML was already there

Other approaches considered

1. Use the nullish coalescing operator in the expression (already works today):

<h1 x-text="title ?? 'Not loaded yet'">Not loaded yet</h1>

For x-html:

<section x-html="items ?? $el.innerHTML">
    <em>Loading...</em>
</section>

This is zero new API surface and already handles the use case. The only downside is the $el.innerHTML approach for x-html is slightly verbose for complex fallback HTML — but it works.

2. Use x-show or x-if to conditionally display:

<h1 x-show="title" x-text="title"></h1>
<h1 x-show="!title">Not loaded yet</h1>

More verbose but also zero new API.

3. This PR's approach — a dedicated modifier. Saves a few characters in the expression but adds permanent public API surface to two directives.

Changes Made

No changes made. This is a feature scope question for Caleb.

Test Results

  • x-text.spec.js: 4/4 passing (with fix), 3/4 passing (without fix — new test correctly fails)
  • x-html.spec.js: 5/5 passing (with fix), 4/5 passing (without fix — new test correctly fails)
  • CI: passing

The tests are well-written and correctly isolate the feature behavior. They fail without the implementation, confirming they're testing the right thing.

Code Review

If this feature were to be accepted, these issues need fixing first:

  1. Style: semicolonsx-html.js:10 and x-text.js:9 both have value = value ?? null; with semicolons. Alpine doesn't use semicolons.

  2. Style: trailing whitespacex-html.js:19 and x-text.js:14 have trailing spaces after }).

  3. Naming: ignore-nullish breaks convention — Nearly every Alpine modifier is a single word (fill, lazy, trim, camel, important, immediate). ignore-nullish is a hyphenated two-word modifier. The word "nullish" is also JavaScript jargon — most Alpine users think in terms of "null" or "empty", not the TC39 spec term "nullish."

  4. Malformed HTML in testx-html.spec.js:59: the <button> tag is never closed (missing >). It happens to work because browsers are forgiving, but it's sloppy.

  5. The value ?? null coercion is indirect — The code converts undefined to null, then only checks !== null. This works but is roundabout. value == null (loose equality) already catches both null and undefined in one check, no coercion needed.

Security

No security concerns identified. The modifier only gates whether innerHTML/textContent is set — it doesn't change what values can be set.

Verdict

Lean toward closing. The use case is real but already solvable with existing Alpine expressions (x-text="title ?? 'fallback'"). Adding a modifier for this means:

  • Permanent API surface on two directives to maintain forever
  • A naming precedent (ignore-nullish) that breaks Alpine's single-word modifier convention
  • JavaScript jargon ("nullish") in the public API that non-JS-expert users won't immediately grok
  • Zero community demand (no reactions on the PR or linked issues)

The "laziest correct solution" here is the one Alpine already has: ?? in expressions. A modifier saves maybe 10 characters per usage but costs ongoing API complexity.

If Caleb still wants this feature, the naming should be reconsidered — something single-word like .optional or .nullable would fit Alpine conventions better. And the style issues above need fixing.


Reviewed by Claude

@calebporzio
Copy link
Collaborator

going to pass as you can accomplish this without us adding a new API. thanks!

@calebporzio calebporzio closed this Feb 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants