How to create a nested page?

Is there a way to generate a page nested to a sub directory? I’m looking for something similar to this:

$ yarn rw g page AdminUsers /admin/users
  ✔ Generating page files...
    ✔ Successfully wrote file `./web/src/pages/Admin/UsersPage/UsersPage.stories.tsx`
    ✔ Successfully wrote file `./web/src/pages/Admin/UsersPage/UsersPage.test.tsx`
    ✔ Successfully wrote file `./web/src/pages/Admin/UsersPage/UsersPage.tsx`
  ✔ Updating routes file...
  ✔ Generating types ...
✨  Done in 7.72s.

However the CLI generates following structure:

$ yarn rw g page AdminUsers /admin/users
  ✔ Generating page files...
    ✔ Successfully wrote file `./web/src/pages/AdminUsersPage/AdminUsersPage.stories.tsx`
    ✔ Successfully wrote file `./web/src/pages/AdminUsersPage/AdminUsersPage.test.tsx`
    ✔ Successfully wrote file `./web/src/pages/AdminUsersPage/AdminUsersPage.tsx`
  ✔ Updating routes file...
  ✔ Generating types ...
✨  Done in 7.72s.

Hey @iam there’s not yet but that’s been one of the most-requested features. I started a PR for it and we’ve settled on an API. I might not have updated the PR with those details yet though. Note that this PR is just a stub! I still have a lot of local changes I haven’t pushed up yet.

Other things took up my attention this past month but I plan on coming back to it now that the v0.39 RC is out.

1 Like

Thank you @dom for your reply! Do you know whether redwoodjs tooling (@redwoodjs/structure package, CLI, IDE) will properly handle a nested page if I just create everything manually?

Anton! Welcome back. Not sure if you saw some messages from me about the Contributors Meetup happening at a new time, once per month. It would be great to see you again at a future meetup!

Hope you’re doing well.

1 Like

Great question; I’m not sure! The structure package hasn’t been updated in quite some time and I won’t be updating it in that PR. It’s definitely in need of some TLC, and I think it is actually getting some. I just don’t have the ETA on it.

But that PR updates the RedwoodJS CLI so it will be able to generate pages in nested subdirectories.

I’m not sure if I answered your question though—is that what you meant?

Thank you @dom. I’m not sure, but I guess the structure package is responsible for generating TS typings. So, if it’s outdated at the moment, I would probably prefer to have a flat pages structure rather than hurt the DX in the VS Code.


Thank you @thedavid for the warm welcome :blush:! I would be glad to. It seems that finally I would be able to use RedwoodJS for a production project. I’m doing a thorough POC right now, and massively impressed and appreciate everything you have done so far!

Oh, and happy Thanksgiving to everyone who celebrates! :turkey: :tada: :slightly_smiling_face:

1 Like

Nice to meet you Anton - happy Thanksgiving to you as well,

Short answer: You can nest pages and types will be generated that match.

You’ll just need to run yarn rw g types once you’ve relocated them.

Here I’m doing just that, nesting UserPage in /admin/user:

Just a note: I’m electing to divide my pages by service - so my generated types look a bit weird.
If you use the structure described in your original post, it’ll generate more friendly names.

image

Which results in the following being generated:

// .redwood/types/includes/web-routesPages.d.ts

import AdminUserUserPageType from 'my-app/web/src/pages/Admin/User/UserPage/UserPage'
import AdminUserUsersPageType from 'my-app/web/src/pages/Admin/User/UsersPage/UsersPage'

declare global {
  const AdminUserUserPage: typeof AdminUserUserPageType
  const AdminUserUsersPage: typeof AdminUserUsersPageType
}

Which I’m free to use in Routes.tsx, without breaking Redwood’s importing.

You can also see the weirdness I talked about - I have to reference my pages as AdminUserUserPage and AdminUserUsersPage. If the /user directory didn’t exist, I wouldn’t have to.

<>
// ...
<Set private role="admin" unauthenticated="home">
  <Route path="/admin/users/{id}" page={AdminUserUserPage} name="adminUser" />
  <Route path="/admin/users" page={AdminUserUsersPage} name="adminUsers" />
</Set>
// ...
</>

And then naming the route "adminUser" was a personal preference.

Hope it helps!