diff --git a/docs/docs/authentication.md b/docs/docs/authentication.md index a742628a4754..cef3754ea978 100644 --- a/docs/docs/authentication.md +++ b/docs/docs/authentication.md @@ -130,12 +130,11 @@ const Routes = () => { // highlight-start - - {/* Or... */} + // highlight-end - + ) } @@ -153,9 +152,9 @@ const Routes = () => { - + - + // highlight-next-line @@ -163,9 +162,9 @@ const Routes = () => { // highlight-next-line - + - + ) } diff --git a/docs/docs/how-to/role-based-access-control.md b/docs/docs/how-to/role-based-access-control.md index 7e91ca9eec6a..da138d62d71f 100644 --- a/docs/docs/how-to/role-based-access-control.md +++ b/docs/docs/how-to/role-based-access-control.md @@ -238,52 +238,52 @@ export const getCurrentUser = async (decoded) => { #### How to Protect a Route -To protect a `Private` route for access by a single role: +To protect a `PrivateSet` route for access by a single role: ```jsx -import { Router, Route, Private } from '@redwoodjs/router' +import { Router, Route, PrivateSet } from '@redwoodjs/router' const Routes = () => { return ( - + - + ) } ``` -To protect a `Private` route for access by a multiple roles: +To protect a `PrivateSet` route for access by a multiple roles: ```jsx -import { Router, Route, Private } from '@redwoodjs/router' +import { Router, Route, PrivateSet } from '@redwoodjs/router' const Routes = () => { return ( - + - + ) } ``` -> Note: If you are using `Set` you can use its `private` attribute instead of the `` component. +> Note: If you are using `Set` you can use its `private` attribute instead of the `` component. If the currentUser is not assigned the role, they will be redirected to the page specified in the `unauthenticated` property. Therefore, you can define a specific page to be seen when attempting to access the protected route and denied access such as a "forbidden" page: ```jsx -import { Router, Route, Private } from '@redwoodjs/router' +import { Router, Route, PrivateSet } from '@redwoodjs/router' const Routes = () => { return ( - + - + diff --git a/docs/docs/prerender.md b/docs/docs/prerender.md index e0cb23e0887f..2ac27195086f 100644 --- a/docs/docs/prerender.md +++ b/docs/docs/prerender.md @@ -56,16 +56,16 @@ This will prerender your NotFoundPage to `404.html` in your dist folder. Note th For Private Routes, Redwood prerenders your Private Routes' `whileLoadingAuth` prop: ```jsx - + // Loading is shown while we're checking to see if the user's logged in } prerender/> - + ``` ### Rendering skeletons while authenticating Sometimes you want to render the shell of the page, while you wait for your authentication checks to happen. This can make the experience feel a lot snappier to the user, since they don't wait on a blank screen while their credentials are checked. -To do this, make use of the `whileLoadingAuth` prop on `` or a `` in your Routes file. For example, if we have a dashboard that you need to be logged in to access: +To do this, make use of the `whileLoadingAuth` prop on `` in your Routes file. For example, if we have a dashboard that you need to be logged in to access: ```js ./web/src/Routes.{tsx,js} // This renders the layout with skeleton loaders in the content area diff --git a/docs/docs/router.md b/docs/docs/router.md index 4bd2af5a7d51..08bbbfdd6d8f 100644 --- a/docs/docs/router.md +++ b/docs/docs/router.md @@ -46,8 +46,6 @@ The `path` prop specifies the URL path to match, starting with the beginning sla Some pages should only be visible to authenticated users. -We support this using private ``s or the `` component. Read more [further down](#private-set). - ## Sets of Routes You can group Routes into sets using the `Set` component. `Set` allows you to wrap a set of Routes in another component or array of components—usually a Context, a Layout, or both: @@ -145,16 +143,16 @@ Here's an example of how you'd use a private set: ``` -Private routes are important and should be easy to spot in your Routes file. The larger your Routes file gets, the more difficult it will probably become to find `` among your other Sets. So we also provide a `` component that's just an alias for ``. Most of our documentation uses ``. +Private routes are important and should be easy to spot in your Routes file. The larger your Routes file gets, the more difficult it will probably become to find `` among your other Sets. So we also provide a `` component that's just an alias for ``. Most of our documentation uses ``. -Here's the same example again, but now using `` +Here's the same example again, but now using `` ```jsx title="Routes.js" - + - + ``` @@ -164,9 +162,9 @@ To protect `Private` routes for access by a single role: ```jsx title="Routes.js" - + - + @@ -176,9 +174,9 @@ To protect `Private` routes for access by multiple roles: ```jsx title="Routes.js" - + - + @@ -574,13 +572,13 @@ When the lazy-loaded page is loading, `PageLoadingContext.Consumer` will pass `{ Let's say you have a dashboard area on your Redwood app, which can only be accessed after logging in. When Redwood Router renders your private page, it will first fetch the user's details, and only render the page if it determines the user is indeed logged in. -In order to display a loader while auth details are being retrieved you can add the `whileLoadingAuth` prop to your private ``, `` or the `` component: +In order to display a loader while auth details are being retrieved you can add the `whileLoadingAuth` prop to your private ``, `` or the `` component: ```jsx //Routes.js - {/* other routes */} - + ``` diff --git a/docs/docs/tutorial/chapter0/what-is-redwood.md b/docs/docs/tutorial/chapter0/what-is-redwood.md index 95e2e4de08ed..de104efb50e8 100644 --- a/docs/docs/tutorial/chapter0/what-is-redwood.md +++ b/docs/docs/tutorial/chapter0/what-is-redwood.md @@ -41,10 +41,10 @@ const Routes = () => { - + - + @@ -54,7 +54,7 @@ const Routes = () => { } ``` -You can probably get a sense of how all of this works without ever having seen a Redwood route before! Some routes can be marked as `` and will not be accessible without being logged in. Others can be wrapped in a "layout" (again, just a React component) to provide common styling shared between pages in your app. +You can probably get a sense of how all of this works without ever having seen a Redwood route before! Some routes can be marked as `` and will not be accessible without being logged in. Others can be wrapped in a "layout" (again, just a React component) to provide common styling shared between pages in your app. #### Prerender @@ -66,7 +66,7 @@ This is Redwood's version of static site generation, aka SSG. ### Authentication -The `` route limits access to users that are authenticated, but how do they authenticate? Redwood includes integrations to many popular third party authentication hosts (including [Auth0](https://auth0.com/), [Supabase](https://supabase.com/docs/guides/auth) and [Clerk](https://clerk.com/)). You can also [host your own auth](https://redwoodjs.com/docs/auth/dbauth), or write your own [custom authentication](https://redwoodjs.com/docs/auth/custom) option. If going self-hosted, we include login, signup, and reset password pages, as well as the option to include TouchID/FaceID and third party biometric readers! +The `` route limits access to users that are authenticated, but how do they authenticate? Redwood includes integrations to many popular third party authentication hosts (including [Auth0](https://auth0.com/), [Supabase](https://supabase.com/docs/guides/auth) and [Clerk](https://clerk.com/)). You can also [host your own auth](https://redwoodjs.com/docs/auth/dbauth), or write your own [custom authentication](https://redwoodjs.com/docs/auth/custom) option. If going self-hosted, we include login, signup, and reset password pages, as well as the option to include TouchID/FaceID and third party biometric readers! Once authenticated, how do you know what a user is allowed to do or not do? Redwood includes helpers for [role-based access control](https://redwoodjs.com/docs/how-to/role-based-access-control-rbac) that integrates on both the front- and backend. diff --git a/docs/docs/tutorial/chapter4/authentication.md b/docs/docs/tutorial/chapter4/authentication.md index 1cee5a8d3dd4..80b403b7f022 100644 --- a/docs/docs/tutorial/chapter4/authentication.md +++ b/docs/docs/tutorial/chapter4/authentication.md @@ -195,7 +195,7 @@ Try reloading the Posts admin and we'll see something that's 50% correct: ![image](https://user-images.githubusercontent.com/300/146462761-d21c93f0-289a-4e11-bccf-8e4e68f21438.png) -Going to the admin section now prevents a non-logged in user from seeing posts, great! This is the result of the `@requireAuth` directive in `api/src/graphql/posts.sdl.{js,ts}`: you're not authenticated so GraphQL will not respond to your request for data. But, ideally they wouldn't be able to see the admin pages themselves. Let's fix that with a new component in the Routes file, ``: +Going to the admin section now prevents a non-logged in user from seeing posts, great! This is the result of the `@requireAuth` directive in `api/src/graphql/posts.sdl.{js,ts}`: you're not authenticated so GraphQL will not respond to your request for data. But, ideally they wouldn't be able to see the admin pages themselves. Let's fix that with a new component in the Routes file, ``: @@ -213,7 +213,7 @@ const Routes = () => { return ( // highlight-next-line - + @@ -221,7 +221,7 @@ const Routes = () => { // highlight-next-line - + @@ -252,7 +252,7 @@ const Routes = () => { return ( // highlight-next-line - + @@ -260,7 +260,7 @@ const Routes = () => { // highlight-next-line - + @@ -278,7 +278,7 @@ export default Routes -We wrap the routes we want to be private (that is, only accessible when logged in) in the `` component, and tell our app where to send them if they are unauthenticated. In this case they should go to the `home` route. +We wrap the routes we want to be private (that is, only accessible when logged in) in the `` component, and tell our app where to send them if they are unauthenticated. In this case they should go to the `home` route. Try going back to [http://localhost:8910/admin/posts](http://localhost:8910/admin/posts) now and—yikes! @@ -288,7 +288,7 @@ Well, we couldn't get to the admin pages, but we also can't see our blog posts a It's because the `posts` query in `posts.sdl.{js,ts}` is used by both the homepage *and* the posts admin page. Since it has the `@requireAuth` directive, it's locked down and can only be accessed when logged in. But we *do* want people that aren't logged in to be able to view the posts on the homepage! -Now that our admin pages are behind a `` route, what if we set the `posts` query to be `@skipAuth` instead? Let's try: +Now that our admin pages are behind a `` route, what if we set the `posts` query to be `@skipAuth` instead? Let's try: @@ -888,7 +888,7 @@ You can generate a new value with the `yarn rw g secret` command. It only output ## Wrapping Up -Believe it or not, that's pretty much it for authentication! You can use the combination of `@requireAuth` and `@skipAuth` directives to lock down access to GraphQL query/mutations, and the `` component to restrict access to entire pages of your app. If you only want to restrict access to certain components, or certain parts of a component, you can always get `isAuthenticated` from the `useAuth()` hook and then render one thing or another. +Believe it or not, that's pretty much it for authentication! You can use the combination of `@requireAuth` and `@skipAuth` directives to lock down access to GraphQL query/mutations, and the `` component to restrict access to entire pages of your app. If you only want to restrict access to certain components, or certain parts of a component, you can always get `isAuthenticated` from the `useAuth()` hook and then render one thing or another. Head over to the Redwood docs to read more about [self-hosted](../../auth/dbauth.md) and [third-party authentication](../../authentication.md#official-integrations). diff --git a/docs/versioned_docs/version-6.0/authentication.md b/docs/versioned_docs/version-6.0/authentication.md index a742628a4754..d026aa91bb17 100644 --- a/docs/versioned_docs/version-6.0/authentication.md +++ b/docs/versioned_docs/version-6.0/authentication.md @@ -117,11 +117,11 @@ Much of what the functions it returns do is self explanatory, but the options th ### Protecting routes -You can require that a user be authenticated to navigate to a route by wrapping it in the `Private` component or the `Set` component with the `private` prop set to `true`. +You can require that a user be authenticated to navigate to a route by wrapping it in the `PrivateSet` component. An unauthenticated user will be redirected to the route specified in either component's `unauthenticated` prop: ```tsx title="web/src/Routes.tsx" -import { Router, Route, Private } from '@redwoodjs/router' +import { Router, Route, PrivateSet } from '@redwoodjs/router' const Routes = () => { return ( @@ -130,21 +130,21 @@ const Routes = () => { // highlight-start - + {/* Or... */} // highlight-end - + ) } ``` -You can also restrict access by role by passing a role or an array of roles to the `Private` or `Set` component's `hasRole` prop: +You can also restrict access by role by passing a role or an array of roles to the `PrivateSet` component's `hasRole` prop: ```tsx title="web/src/Routes.tsx" -import { Router, Route, Private, Set } from '@redwoodjs/router' +import { Router, Route, PrivateSet, Set } from '@redwoodjs/router' const Routes = () => { return ( @@ -153,9 +153,9 @@ const Routes = () => { - + - + // highlight-next-line @@ -163,9 +163,9 @@ const Routes = () => { // highlight-next-line - + - + ) } diff --git a/docs/versioned_docs/version-6.0/how-to/role-based-access-control.md b/docs/versioned_docs/version-6.0/how-to/role-based-access-control.md index 7e91ca9eec6a..dbe467f68964 100644 --- a/docs/versioned_docs/version-6.0/how-to/role-based-access-control.md +++ b/docs/versioned_docs/version-6.0/how-to/role-based-access-control.md @@ -246,9 +246,9 @@ import { Router, Route, Private } from '@redwoodjs/router' const Routes = () => { return ( - + - + ) } @@ -262,28 +262,28 @@ import { Router, Route, Private } from '@redwoodjs/router' const Routes = () => { return ( - + - + ) } ``` -> Note: If you are using `Set` you can use its `private` attribute instead of the `` component. +> Note: If you are using `Set` you can use its `private` attribute instead of the `` component. If the currentUser is not assigned the role, they will be redirected to the page specified in the `unauthenticated` property. Therefore, you can define a specific page to be seen when attempting to access the protected route and denied access such as a "forbidden" page: ```jsx -import { Router, Route, Private } from '@redwoodjs/router' +import { Router, Route, PrivateSet } from '@redwoodjs/router' const Routes = () => { return ( - + - + diff --git a/docs/versioned_docs/version-6.0/prerender.md b/docs/versioned_docs/version-6.0/prerender.md index 210e01358341..fa467aea495c 100644 --- a/docs/versioned_docs/version-6.0/prerender.md +++ b/docs/versioned_docs/version-6.0/prerender.md @@ -56,16 +56,16 @@ This will prerender your NotFoundPage to `404.html` in your dist folder. Note th For Private Routes, Redwood prerenders your Private Routes' `whileLoadingAuth` prop: ```jsx - + // Loading is shown while we're checking to see if the user's logged in } prerender/> - + ``` ### Rendering skeletons while authenticating Sometimes you want to render the shell of the page, while you wait for your authentication checks to happen. This can make the experience feel a lot snappier to the user, since they don't wait on a blank screen while their credentials are checked. -To do this, make use of the `whileLoadingAuth` prop on `` or a `` in your Routes file. For example, if we have a dashboard that you need to be logged in to access: +To do this, make use of the `whileLoadingAuth` prop on `` in your Routes file. For example, if we have a dashboard that you need to be logged in to access: ```js ./web/src/Routes.{tsx,js} // This renders the layout with skeleton loaders in the content area diff --git a/docs/versioned_docs/version-6.0/router.md b/docs/versioned_docs/version-6.0/router.md index 4bd2af5a7d51..98d1493d9ab9 100644 --- a/docs/versioned_docs/version-6.0/router.md +++ b/docs/versioned_docs/version-6.0/router.md @@ -46,7 +46,7 @@ The `path` prop specifies the URL path to match, starting with the beginning sla Some pages should only be visible to authenticated users. -We support this using private ``s or the `` component. Read more [further down](#private-set). +We support this using private `` component. Read more [further down](#private-set). ## Sets of Routes @@ -145,40 +145,40 @@ Here's an example of how you'd use a private set: ``` -Private routes are important and should be easy to spot in your Routes file. The larger your Routes file gets, the more difficult it will probably become to find `` among your other Sets. So we also provide a `` component that's just an alias for ``. Most of our documentation uses ``. +Private routes are important and should be easy to spot in your Routes file. The larger your Routes file gets, the more difficult it will probably become to find `` among your other Sets. So we also provide a `` component that's just an alias for ``. Most of our documentation uses ``. -Here's the same example again, but now using `` +Here's the same example again, but now using `` ```jsx title="Routes.js" - + - + ``` For more fine-grained control, you can specify `roles` (which takes a string for a single role or an array of roles), and the router will check to see that the current user is authorized before giving them access to the Route. If they're not, they will be redirected to the page specified in the `unauthenticated` prop, such as a "forbidden" page. Read more about Role-based Access Control in Redwood [here](how-to/role-based-access-control.md). -To protect `Private` routes for access by a single role: +To protect `PrivateSet` routes for access by a single role: ```jsx title="Routes.js" - + - + ``` -To protect `Private` routes for access by multiple roles: +To protect `PrivateSet` routes for access by multiple roles: ```jsx title="Routes.js" - + - + @@ -574,13 +574,13 @@ When the lazy-loaded page is loading, `PageLoadingContext.Consumer` will pass `{ Let's say you have a dashboard area on your Redwood app, which can only be accessed after logging in. When Redwood Router renders your private page, it will first fetch the user's details, and only render the page if it determines the user is indeed logged in. -In order to display a loader while auth details are being retrieved you can add the `whileLoadingAuth` prop to your private ``, `` or the `` component: +In order to display a loader while auth details are being retrieved you can add the `whileLoadingAuth` prop to your private ``, `` component: ```jsx //Routes.js - {/* other routes */} - + ``` diff --git a/docs/versioned_docs/version-6.0/tutorial/chapter4/authentication.md b/docs/versioned_docs/version-6.0/tutorial/chapter4/authentication.md index 7ab3656994c4..562d7b34b0a3 100644 --- a/docs/versioned_docs/version-6.0/tutorial/chapter4/authentication.md +++ b/docs/versioned_docs/version-6.0/tutorial/chapter4/authentication.md @@ -195,7 +195,7 @@ Try reloading the Posts admin and we'll see something that's 50% correct: ![image](https://user-images.githubusercontent.com/300/146462761-d21c93f0-289a-4e11-bccf-8e4e68f21438.png) -Going to the admin section now prevents a non-logged in user from seeing posts, great! This is the result of the `@requireAuth` directive in `api/src/graphql/posts.sdl.{js,ts}`: you're not authenticated so GraphQL will not respond to your request for data. But, ideally they wouldn't be able to see the admin pages themselves. Let's fix that with a new component in the Routes file, ``: +Going to the admin section now prevents a non-logged in user from seeing posts, great! This is the result of the `@requireAuth` directive in `api/src/graphql/posts.sdl.{js,ts}`: you're not authenticated so GraphQL will not respond to your request for data. But, ideally they wouldn't be able to see the admin pages themselves. Let's fix that with a new component in the Routes file, ``: @@ -213,7 +213,7 @@ const Routes = () => { return ( // highlight-next-line - + @@ -221,7 +221,7 @@ const Routes = () => { // highlight-next-line - + @@ -241,7 +241,7 @@ export default Routes ```jsx title="web/src/Routes.tsx" // highlight-next-line -import { Private, Router, Route, Set } from '@redwoodjs/router' +import { PrivateSet, Router, Route, Set } from '@redwoodjs/router' import ScaffoldLayout from 'src/layouts/ScaffoldLayout' import BlogLayout from 'src/layouts/BlogLayout' @@ -252,7 +252,7 @@ const Routes = () => { return ( // highlight-next-line - + @@ -260,7 +260,7 @@ const Routes = () => { // highlight-next-line - + @@ -278,7 +278,7 @@ export default Routes -We wrap the routes we want to be private (that is, only accessible when logged in) in the `` component, and tell our app where to send them if they are unauthenticated. In this case they should go to the `home` route. +We wrap the routes we want to be private (that is, only accessible when logged in) in the `` component, and tell our app where to send them if they are unauthenticated. In this case they should go to the `home` route. Try going back to [http://localhost:8910/admin/posts](http://localhost:8910/admin/posts) now and—yikes! @@ -288,7 +288,7 @@ Well, we couldn't get to the admin pages, but we also can't see our blog posts a It's because the `posts` query in `posts.sdl.{js,ts}` is used by both the homepage *and* the posts admin page. Since it has the `@requireAuth` directive, it's locked down and can only be accessed when logged in. But we *do* want people that aren't logged in to be able to view the posts on the homepage! -Now that our admin pages are behind a `` route, what if we set the `posts` query to be `@skipAuth` instead? Let's try: +Now that our admin pages are behind a `` route, what if we set the `posts` query to be `@skipAuth` instead? Let's try: @@ -888,7 +888,7 @@ You can generate a new value with the `yarn rw g secret` command. It only output ## Wrapping Up -Believe it or not, that's pretty much it for authentication! You can use the combination of `@requireAuth` and `@skipAuth` directives to lock down access to GraphQL query/mutations, and the `` component to restrict access to entire pages of your app. If you only want to restrict access to certain components, or certain parts of a component, you can always get `isAuthenticated` from the `useAuth()` hook and then render one thing or another. +Believe it or not, that's pretty much it for authentication! You can use the combination of `@requireAuth` and `@skipAuth` directives to lock down access to GraphQL query/mutations, and the `` component to restrict access to entire pages of your app. If you only want to restrict access to certain components, or certain parts of a component, you can always get `isAuthenticated` from the `useAuth()` hook and then render one thing or another. Head over to the Redwood docs to read more about [self-hosted](../../auth/dbauth.md) and [third-party authentication](../../authentication.md#official-integrations). diff --git a/docs/versioned_docs/version-6.0/tutorial/chapter7/rbac.md b/docs/versioned_docs/version-6.0/tutorial/chapter7/rbac.md index c7603aec30c6..bac9123c38c4 100644 --- a/docs/versioned_docs/version-6.0/tutorial/chapter7/rbac.md +++ b/docs/versioned_docs/version-6.0/tutorial/chapter7/rbac.md @@ -156,21 +156,21 @@ export const hasRole = (roles: AllowedRoles): boolean => { ### Restricting Access via Routes -The easiest way to prevent access to an entire URL is via the Router. The `` component takes a prop `roles` in which you can give a list of only those role(s) that should have access: +The easiest way to prevent access to an entire URL is via the Router. The `` component takes a prop `roles` in which you can give a list of only those role(s) that should have access: ```jsx title="web/src/Routes.jsx" // highlight-next-line - + - + ``` diff --git a/packages/internal/src/__tests__/fixtures/nestedPages/web/src/Routes.js b/packages/internal/src/__tests__/fixtures/nestedPages/web/src/Routes.js index 43cf0d3c5bc7..f636475bd3c3 100644 --- a/packages/internal/src/__tests__/fixtures/nestedPages/web/src/Routes.js +++ b/packages/internal/src/__tests__/fixtures/nestedPages/web/src/Routes.js @@ -7,7 +7,7 @@ // 'src/pages/HomePage/HomePage.js' -> HomePage // 'src/pages/Admin/BooksPage/BooksPage.js' -> AdminBooksPage -import { Private, Route, Router, Set } from '@redwoodjs/router' +import { PrivateSet, Route, Router, Set } from '@redwoodjs/router' import AdminLayout from 'src/layouts/AdminLayout/AdminLayout' import MainLayout from 'src/layouts/MainLayout/MainLayout' @@ -44,7 +44,7 @@ const Routes = () => { - + @@ -52,7 +52,7 @@ const Routes = () => { - + ) } diff --git a/packages/structure/src/model/RWRoute.ts b/packages/structure/src/model/RWRoute.ts index 5a66caa7a69a..0d54fb180e62 100644 --- a/packages/structure/src/model/RWRoute.ts +++ b/packages/structure/src/model/RWRoute.ts @@ -192,7 +192,7 @@ export class RWRoute extends BaseNode { if (this.isPrivate && this.isNotFound) { yield err( this.jsxNode!, - "The 'Not Found' page cannot be within a tag" + "The 'Not Found' page cannot be within a or a tag" ) } if (this.isNotFound && this.path) { diff --git a/packages/testing/src/web/__tests__/MockRouter.test.tsx b/packages/testing/src/web/__tests__/MockRouter.test.tsx index fc4953652153..6a1ef2f78a3d 100644 --- a/packages/testing/src/web/__tests__/MockRouter.test.tsx +++ b/packages/testing/src/web/__tests__/MockRouter.test.tsx @@ -2,7 +2,7 @@ import React from 'react' import { render } from '@testing-library/react' -import { Route, Private } from '@redwoodjs/router' +import { Route, PrivateSet } from '@redwoodjs/router' import { routes, Router } from '../MockRouter' @@ -14,10 +14,10 @@ describe('MockRouter', () => { - + - + ) diff --git a/packages/vite/src/__tests__/fixtures/nestedPages/web/src/Routes.js b/packages/vite/src/__tests__/fixtures/nestedPages/web/src/Routes.js index 43cf0d3c5bc7..f636475bd3c3 100644 --- a/packages/vite/src/__tests__/fixtures/nestedPages/web/src/Routes.js +++ b/packages/vite/src/__tests__/fixtures/nestedPages/web/src/Routes.js @@ -7,7 +7,7 @@ // 'src/pages/HomePage/HomePage.js' -> HomePage // 'src/pages/Admin/BooksPage/BooksPage.js' -> AdminBooksPage -import { Private, Route, Router, Set } from '@redwoodjs/router' +import { PrivateSet, Route, Router, Set } from '@redwoodjs/router' import AdminLayout from 'src/layouts/AdminLayout/AdminLayout' import MainLayout from 'src/layouts/MainLayout/MainLayout' @@ -44,7 +44,7 @@ const Routes = () => { - + @@ -52,7 +52,7 @@ const Routes = () => { - + ) }