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

Directory based router #45

Open
akku1139 opened this issue Feb 12, 2024 · 10 comments
Open

Directory based router #45

akku1139 opened this issue Feb 12, 2024 · 10 comments
Labels
enhancement New feature or request

Comments

@akku1139
Copy link

What is the feature you are proposing?

I would like to do directory-based routing like SvelteKit and Next.js App Router.
Either in a way like (+)page.ts or separate files for each HTTP method and route them like +get.ts and +post.ts.

@akku1139 akku1139 added the enhancement New feature or request label Feb 12, 2024
@EdamAme-x
Copy link

I agree with this idea.
I think it is a great way to solve the complexity of routing.

@yusukebe
Copy link
Member

Hi @akku1139 !

Thanks for your proposal.

I'm not 100% sure I understand the directory routing for SvelteKit and Next.js App Router, but what is the difference between using index.tsx as a base as shown below?

app/routes/about/index.tsx

Of course, it would be interesting to be able to separate files for each request, such as GET and POST. In that case, I think it would be nice to have a rule for file names such as index.get.tsx or index.post.tsx, and the results they default export to correspond to GET or POST.

@babie
Copy link

babie commented Feb 16, 2024

Personally, I think that pros of directory-based-router equals pros of pakcage by feature.
(cf. package by feature のススメ (ja))

I don't mind using index.tsx instead of page.tsx, but I would like a filename convention(e.g. prefix rule) that the router will ignore.
This way, we can freely place related files (e.g. foo.module.css) without getting caught in routing.

@akku1139
Copy link
Author

If you use index.get.tsx etc., there is a possibility that a route of /index.get will be created.

If it can create rules in the package, the problem will be solved,
but setting different rules depending on the project may make it difficult to understand.

If you decide on a fixed root file in HonoX, it will be the same for all projects, so it is easy to understand,
when creating a very small application, it may be easier to make if the file name corresponds to the root.
↓ This is an explanation about SvelteKit's routing.
https://zenn.dev/qwerty/articles/ed1283408bef01

@yusukebe
Copy link
Member

@babie @akku1139

Thanks! Could understand. But I want to have a little bit of time to learn about it and consider it!

@yoshikouki
Copy link

I agree with the pros/cons discussed so far.

On a personal note, I like the current filename rules because they are as clear as the Controller in Ruby on Rails.
(I guess the directory structure under app/routes in honox plays a role similar to routes.rb in Ruby on Rails. I like it because it's more convention-oriented and intuitive.)


Here are some suggestions for a related, but slightly different, client-side component (islands)

Currently, even page-specific client-side components must be placed in app/islands/*.

For example, consider a simple chat application,

.
├── app
│   ├── islands
│   │   ├── chat.tsx # URL `/chats/:id` specific component
│   │   └── online-status.tsx # Global component placed in each routes
│   ├── routes
│   │   ├── chats
│   │   │   ├── [id].tsx
│   │   │   └── index.tsx
│   │   └── index.tsx
  • The islands/online-status.tsx that displays the online status is displayed on each page, so it is not out of place under islands.
  • islands/chat.tsx is a page-specific component, so it would not look good in parallel with online-status.tsx.

I would like to place the client component chat.tsx in the same directory as the server-side component routes/chats/[id].tsx which is closer in purpose (e.g. chat.island.tsx)

.
├── app
│   ├── islands
│   │   └── online-status.tsx
│   ├── routes
│   │   ├── chats
│   │   │   ├── [id]
│   │   │   │   ├── chat.island.tsx
│   │   │   │   └── index.tsx
│   │   │   └── index.tsx
│   │   └── index.tsx

However, we feel that it would be better to manage global common components used on each page in app/islands/* as before.

For your reference

@babie
Copy link

babie commented Feb 26, 2024

I think it is a good idea. However, there is the problem of what to do if you want to create a page called /chats/[id]/chat.island.

I think it is a good idea to prefix it with some special character to prevent it from being included in the routing. For example, ! or something like that.

.
└── app
    ├── islands
    │   └── online-status.tsx
    └── routes
        ├── chats
        │   ├── [id]
        │   │   ├── !chat.island.tsx
        │   │   ├── !chat.module.css
        │   │   └── index.tsx
        │   └── index.tsx
        └── index.tsx

@yusukebe
Copy link
Member

Hi @yoshikouki @babie

I would like to place the client component chat.tsx in the same directory as the server-side component routes/chats/[id].tsx which is closer in purpose (e.g. chat.island.tsx)

+1

I think it is a good idea to prefix it with some special character to prevent it from being included in the routing. For example, ! or something like that.

+1

I think both ideas are great. This means that...

  • We can put Islands components in the route directories with a suffix like island.tsx.
  • Files that we want to treat as components separately from the route file should have a prefix such as !.

These would be simple to implement and easy for users to understand.

@yusukebe
Copy link
Member

Hey!

I've made PR #140, enabling putting an island component, not only in the /app/islands directory. I think this is a good change. So, this will be merged. But if you have any thoughts, please share them!

@yusukebe
Copy link
Member

Hi you all.

I've released v0.1.12. This release includes the new feature which enables placing islands on the same directory of pages instead of /app/islands/*:

./app
├── client.ts
├── global.d.ts
├── routes
│   ├── _renderer.tsx
│   ├── articles
│   │   ├── [id].tsx
│   │   ├── _preview.island.tsx // <=== the prefix should be `_` and the suffix is `.island.tsx`
│   │   └── create.tsx
│   └── index.tsx
├── server.ts
├── style.css
└── utils.ts

This enables directory-based routing. Please try it.

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

No branches or pull requests

5 participants