localvoid/ivi

Add support for ElementDirectives during Server-Side Rendering

localvoid opened this issue · 0 comments

ElementDirective provides an escape hatch to deal with DOM elements directly (dynamic attribute names, vdom-like attributes diffing, adding passive event listeners, etc), but right now element directives are completely ignored during Server-Side Rendering.

The main issue is that in a lot of use cases, element directives doesn't require generating anything during SSR, so the DX should be optimized for writing such directives. The idea is to add some additional syntax to disambiguate between Client-Side Rendering directives and directives that is safe to run during Client-Side and Server-Side Rendering.

Maybe something like this:

Client-Side Directive:

const Example = component((c) => {
  let _e;
  const directive = (element) => { _e = element; };
  return () => htm`<div &=${directive}` />`;
});

Client-Side + Server-Side Directive:

const Example = component((c) => {
  const directive = (element, hydrate) => {
    if (import.meta.env.SSR) {
      return { attributes: `name="value"` };
    }
    if (!hydrate) {
      element.setAttribute("name", "value");
    }
  };
  return () => htm`<div &:ssr=${directive}` />`;
});