localvoid / ivi

Lighweight Embeddable Web UI Library
MIT License
724 stars 22 forks source link

Add support for ElementDirectives during Server-Side Rendering #53

Closed localvoid closed 1 year ago

localvoid commented 1 year ago

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}` />`;
});