Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'use client' or islands dir #2002

Closed
yusukebe opened this issue Jan 17, 2024 · 7 comments
Closed

'use client' or islands dir #2002

yusukebe opened this issue Jan 17, 2024 · 7 comments

Comments

@yusukebe
Copy link
Member

yusukebe commented Jan 17, 2024

Thanks to @usualoma, JSX "Client Components" are working for real. Next, we need to figure out how to integrate it into the framework. Specifically, how to hydrate the Client Components in the HTML rendered by the server.

Here, we discuss "Which component becomes a Client Component?" There are two ways. Using the 'use client' directive and using the islands directory.

'use client'

The 'use client' directive is an API in React, used in Next.js. Although it may not be the original usage of React, we can consider a component with 'use client' at the beginning to be a client component.

'use client'

import { useState } from 'hono/jsx'

const Counter = () => {
  const [count, setCount] = useState(0)
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  )
}

export default Counter

This is @usualoma implementing PoC. There are things we need to improve, but the approach to make it a Vite plugin would be good.

https://github.com/usualoma/hono-dom-hcc

islands directory pattern

The islands directory pattern is an approach that puts the components you want to be client components in a specific directory, such as /app/islands. Fresh uses it.

Sonik also uses this approach. The Vite plugin loads the components in /app/islands and marks them as client components.

'use client' vs islands dir

The following are just a few things I can think of. If there are others, please let me know.

'use client':

  • Pros: You don't have to put it in the specific directory.
  • Pros: "Trendy".
  • Cons: Implementation is a little bit hacky.

islands directory pattern:

  • Pros: Easy to implement; can use Vite's glob import
  • Pros: Can use other UI libraries such as React and Preact. Sonik do it. use client could also use other UI libraries.
  • Cons: You have to put files in a specific directory.

Make it a Vite plugin

If we decide to go either way, it would be implemented as a Vite plugin.


This is just a matter of which component we consider the client component. But we have to decide.

@yusukebe yusukebe added the v4 label Jan 17, 2024
@yusukebe
Copy link
Member Author

@usualoma I want to know your opinion.
@watany-dev @sor4chi @nakasyou @bruceharrison1984 and others! If you have any thoughts, please share them.

@usualoma
Copy link
Member

usualoma commented Jan 17, 2024

Hi, @yusukebe

I was not familiar with islands architecture, so I copied what I knew about Next.js, but I don't have any particular desire to stick to my own way of doing things.

Can use other UI libraries such as React and Preact. Sonik do it.

I don't think this point is Pros only for the islands dir, since it can be achieved by "'use client' + sonik's approach". (can not by my PoC's approach).

Well, I think the separate directories is easy to understand and simple, so I think the islands dir is fine.

If we later decide that we want to use the use client, I think we can add support with that at that time.

@bruceharrison1984
Copy link
Contributor

I like the simplicity of the islands implementation, but one potential big drawback is the inability to use component libraries that make use of use client.

You'd have to wrap each component in an island component to make it work, which is kind of comical because everyone had to wrap components with use client last year due to the opposite problem 😄

I'd put my vote with use client to maximize compatibility with external libraries.

@yusukebe
Copy link
Member Author

@usualoma commented:

I don't think this point is Pros only for the islands dir, since it can be achieved by "'use client' + sonik's approach". (can not by my PoC's approach).

Indeed. That's true. I'll edit the above.

@nakasyou
Copy link
Contributor

I have a idea.

import { Island } from 'hono/jsx'
import Counter from './Counter'

app.get('/', c => c.html(<main>
  <Island island={Counter} props={{}} />
</main>))

How about you my idea?

  • Pros: You don't have to put it in the specific directory.
  • Pros: Implementing this is easier than 'use client'
  • Pros: You can create custom Island wrapper for UI library such as React, Solid.js, Svelte, etc.
  • Cons: May be accidentally used on a server

@emmanuelchucks
Copy link

This might be a tiny bit cleaner

import { Island } from 'hono/jsx'
import Counter from './Counter'

app.get('/', c => c.html(
  <main>
    <Island>
      <Counter props={{}} />
    </Island>
  </main>
))

Although going with "use client" is the safest bet to match with current conventions (just like Suspense and ErrorBoundary) and help those coming from other frameworks.

@yusukebe
Copy link
Member Author

Thanks all! We are going with the "islands dir":

https://github.com/honojs/honox?tab=readme-ov-file#interactions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants