honojs / hono

Web framework built on Web Standards
https://hono.dev
MIT License
18.9k stars 537 forks source link

Feature Request: Components for html middleware #1327

Open niklasgrewe opened 1 year ago

niklasgrewe commented 1 year ago

What is the feature you are proposing?

I really like the html middelware for templating. It's faster than jsx and the code is more readable in my opinion. But can we extend this to support components like in other frameworks like astro or svelte? I imagine something like this:

Instead of writing this:

const home = () => html`
  <h1>Homepage</h1>
  ${card('<p>card content</p>')}
`

const card = (content: string) => html`
  <div>${raw(content)}</div>
`

we can write:

const home = () => html`
  <h1>Homepage</h1>
  <card>
    <p>card content</p>
  </card>
`

const card = () => html`
  <div>
    <slot></slot>
  </div>
`

and with props:

const home = () => html`
  <h1>Homepage</h1>
  <card title="Card title">
    <p>card content</p>
  </card>
`

const card = (title: string) => html`
  <div>
    <h2>${title}</h2>
    <slot></slot>
  </div>
`

To distinguish server-side components from native web components, I would personally consider three approaches:

  1. server-side components always start with a capital letter, as in svelte or astro.
  2. server side components are lowercase, but must not contain a hyphen, which is the requirement for web components
  3. since web components need js, you could for example check if there is a script tag in the template string to register a new web component

unfortunately i don't know how complex it is to add such a feature to the html middleware or whether this will cause performance problems. Of course you can argue that we already got this feature through jsx middleware. However, jsx is slower and the writing doesn't feel as clean and native as html in my opinion. Also, it is easier for me to add <style /> and <script /> tags, because you don't need to add the html wrapper around this, also you do not need a fragment.

Hope you like the idea. Am curious about your feedback

niklasgrewe commented 1 year ago

@usualoma i saw that you brought the html template literals to hono. Thanks for your effort. I really like to work with it because it is absolutely simple but also very performant and powerful.

What do you think about my idea to add components to html template literals as I explained above? Do you think this would be possible without losing simplicity and performance? Similar to you, I don't want html middleware to become "as complex" as jsx, but maybe there is a good middle ground.

I'm looking forward to your feedback.

usualoma commented 1 year ago

Hi @niklasgrewe !

Thanks for the suggestion.

The ability to precompile the following features would be essential to implement and execute them in high performance. When dynamically parsing and executing HTML, it will be much slower than the current JSX.

Implementing it as third-party middleware might be an interesting challenge. Still, I don't think adding such functionality to the html middleware included in the core is a good idea.

const home = () => html`
  <h1>Homepage</h1>
  <card>
    <p>card content</p>
  </card>
`

const card = () => html`
  <div>
    <slot></slot>
  </div>
`
Odas0R commented 11 months ago

I think this is best for a plugin (e.g vite plugin) or just using web components!