enhance-dev / enhance-ssr

Server side render for custom elements.
143 stars 9 forks source link

Render to string in the browser #35

Closed jacobrask closed 1 year ago

jacobrask commented 1 year ago

If I understand it correctly, the pattern described in the docs to Reuse your pure function in the browser will only work if the pure function doesn't return any Enhance Elements in itself - because expanding those happens in this package.

Any thoughts on a variant of this package that uses native browser APIs to parse the rendered HTML to support nested elements?

kristoferjoseph commented 1 year ago

Not sure I'm fully understanding what issue you are running into.

If you code along with the example code from the doc you linked to it will show you how that works.

You can nest elements because they get expanded either during SSR or in the browser if all of the nested elements are defined.

jacobrask commented 1 year ago

Given the following Enhance Elements

// ./app/elements/my-message.mjs
export default function MyMessage({ html, state }) {
  const { attrs = [] } = state;
  const { message = "" } = attrs;

  return html`<h1>${message} <my-button label="Test"></my-button></h1>`;
}

// ./app/elements/my-button.mjs
export default function MyButton({ html, state }) {
  const { attrs = [] } = state;
  const { label = "" } = attrs;

  return html`<button>${label}</button>`;
}

If I then want to add some client side behaviour to MyMessage, this line from the linked example blows away the SSR:d light DOM from my-button.

      this.template.innerHTML = MyMessage({
         html: this.html,
         state: {}
      })
kristoferjoseph commented 1 year ago

Yes that will replace the existing children but if you have the custom elements registered in the browser then it will handle expanding them at that point.

You can also check to see if there are existing children already and not replace them with the template if so.

I have a more complete example here that exemplifies this pattern that I am in the process of publishing and adding to documentation:

https://github.com/kristoferjoseph/enhance-api-example/blob/main/app/browser/todos.mjs#L164