fresh icon indicating copy to clipboard operation
fresh copied to clipboard

Improper DOM nesting leads to fatal `DOMException` on hydration - consider warning in dev mode?

Open CAYdenberg opened this issue 2 years ago • 1 comments

Minimal repro here: https://github.com/CAYdenberg/fresh-nesting-fatal

  • clone it
  • deno task run
  • navigate to localhost:8000/preact-bug
  • open the console

The basics are:

// routes/preact-bug.tsx
export default function PreactBug() {
  return (
    <p>
      <BugIsland />
    </p>
  );
}
// islands/BugIsland.tsx
export default function BugIsland() {
  return <div></div>;
}

I recognize that you can't have a div inside a p. And so what's probably going on is the browser is implicitly closing the p, and Preact gets confused about where it's supposed to create the island.

What I'm wondering about is if there's a better way to alert the developer when this happens. IIRC Fresh was alerting me to other types of nesting errors (regarding tables?) when rendering to string, but not this one. On the client side, it looks like the comment nodes that identify the hydration root (<!--fresh-bugisland_default:0:-->) are getting moved around by the browser, so perhaps there's a way to identify when they aren't "closing" properly around the island and send a more helpful error message?

CAYdenberg avatar Dec 01 '23 23:12 CAYdenberg

It happens when internal Fresh markers (actually Comment nodes) are removed. The start marker, and end marker in this case don't have the same parent.

I was able to make a quick fix so it won't crash. But, It would be problematic after islands are hydrated. A warning or an error of some sort would be the best solution.

The raw HTML:

<p><!--frsh-bugisland_default:0:--><div></div><!--/frsh-bugisland_default:0:--></p>

After browser DOM parsing (p element added):

<p><!--frsh-bugisland_default:0:--></p><div></div><!--/frsh-bugisland_default:0:--><p></p>

After the island is hydrated (div added):

<p></p><div></div><div></div><p></p>

osddeitf avatar Dec 12 '23 14:12 osddeitf