Skip to content

Commit

Permalink
Merge pull request #9404 from marmelab/doc-custom-routes
Browse files Browse the repository at this point in the history
[Doc] Add illustrations to the `<CustomRoutes>` chapter
  • Loading branch information
fzaninotto authored Oct 27, 2023
2 parents f69c7e2 + da6eb0a commit b93c6a2
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 32 deletions.
118 changes: 86 additions & 32 deletions docs/CustomRoutes.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ Alternatively, you can add your custom routes to resources. They will be availab
import { Admin, Resource, CustomRoutes } from 'react-admin';
import { Route } from "react-router-dom";

import dataProvider from './dataProvider';
import { dataProvider } from './dataProvider';
import posts from './posts';
import comments from './comments';
import Settings from './Settings';
import Profile from './Profile';
import { Settings } from './Settings';
import { Profile } from './Profile';

const App = () => (
<Admin dataProvider={dataProvider}>
Expand All @@ -39,18 +39,20 @@ export default App;

Now, when a user browses to `/settings` or `/profile`, the components you defined will appear in the main part of the screen.

**Tip**: Custom routes don't automatically appear in the menu. You have to manually [customize the menu](#adding-custom-routes-to-the-menu) if you want custom routes to be accessible from the menu.

## `children`

`children` of the `<CustomRoutes>` component must be `<Route>` elements from [react-router-dom](https://reactrouter.com/en/6/start/concepts#defining-routes), and map a path with a custom element.
`children` of the `<CustomRoutes>` component must be `<Route>` elements from [react-router-dom](https://reactrouter.com/en/6/start/concepts#defining-routes), mapping a `path` with a custom `element`.

```jsx
// in src/App.js
import { Admin, Resource, CustomRoutes } from 'react-admin';
import { Route } from "react-router-dom";

import dataProvider from './dataProvider';
import Settings from './Settings';
import Profile from './Profile';
import { dataProvider } from './dataProvider';
import { Settings } from './Settings';
import { Profile } from './Profile';

const App = () => (
<Admin dataProvider={dataProvider}>
Expand All @@ -64,19 +66,25 @@ const App = () => (
export default App;
```

You can learn more about the `<Route>` element in the [react-router-dom documentation](https://reactrouter.com/en/6/start/concepts#defining-routes).

## `noLayout`

By default, custom routes render within the application layout (with the menu and the app bar). If you want a custom route to render without the layout, e.g. for registration screens, then provide the `noLayout` prop on the `<CustomRoutes>` element:
By default, custom routes render within the application layout. If you want a custom route to render without the layout, e.g. for registration screens, then provide the `noLayout` prop on the `<CustomRoutes>` element.

<img src="./img/custom-route-nolayout.png" class="no-shadow" alt="custom route with no layout" />

Here is an example of application configuration mixing custom routes with and without layout:

```jsx
// in src/App.js
import { Admin, CustomRoutes } from 'react-admin';
import { Route } from "react-router-dom";

import dataProvider from './dataProvider';
import Register from './Register';
import Settings from './Settings';
import Profile from './Profile';
import { dataProvider } from './dataProvider';
import { Register } from './Register';
import { Settings } from './Settings';
import { Profile } from './Profile';

const App = () => (
<Admin dataProvider={dataProvider}>
Expand All @@ -93,9 +101,13 @@ const App = () => (

As illustrated above, there can be more than one `<CustomRoutes>` element inside an `<Admin>` component.

## Custom Page Title
## Customizing The Page Title

To define the page title (displayed in the app bar), your custom pages can use [the `<Title>` component](./Title.md) from react-admin:
To define the page title (displayed in the app bar), custom pages should use [the `<Title>` component](./Title.md).

<img src="./img/custom-route-title.png" class="no-shadow" alt="custom route title" />

Here is a simple example:

```jsx
// in src/Settings.js
Expand All @@ -117,22 +129,11 @@ export default Settings;

`<Title>` uses a [React Portal](https://react.dev/reference/react-dom/createPortal), so it doesn't matter *where* you put it in your component. The title will always be rendered in the app bar.

## Linking To Custom Routes
## Adding Custom Routes to the Menu

You can link to your pages using [react-router's Link component](https://reactrouter.com/en/main/components/link):
To add your custom pages to the navigation menu, you have to replace the default menu by a [custom menu](./Menu.md) with entries for the custom pages.

```jsx
import { Link as RouterLink } from 'react-router-dom';
import { Link } from '@mui/material';

const SettingsButton = () => (
<Link component={RouterLink} to="/settings">
Settings
</Link>
);
```

Alternately, create a [custom menu](./Menu.md) with entries for the custom pages.
First, create a custom menu. Make sure to use the same value in the `<Menu.Item to>` prop as in the `<Route path>` prop.

```jsx
// in src/MyMenu.js
Expand All @@ -143,23 +144,76 @@ import PeopleIcon from '@mui/icons-material/People';
export const MyMenu = () => (
<Menu>
<Menu.DashboardItem />
<Menu.ResourceItem name="posts" />
<Menu.ResourceItem name="comments" />
<Menu.ResourceItems />
<Menu.Item to="/settings" primaryText="Users" leftIcon={<SettingsIcon />}/>
<Menu.Item to="/profile" primaryText="Miscellaneous" leftIcon={<PeopleIcon />}/>
</Menu>
);
```

Next, pass the custom menu to a custom `<Layout>` component:

```jsx
// in src/MyLayout.js
import { Layout } from 'react-admin';
import { MyMenu } from './MyMenu';

export const MyLayout = (props) => <Layout {...props} menu={MyMenu} />;
```

Finally, pass the custom `<Layout>` component to `<Admin>`:

```jsx
// in src/App.js
import { Admin, Resource, CustomRoutes } from 'react-admin';
import { Route } from "react-router-dom";

import { dataProvider } from './dataProvider';
import { MyLayout } from './MyLayout';
import posts from './posts';
import comments from './comments';
import { Settings } from './Settings';
import { Profile } from './Profile';

const App = () => (
<Admin dataProvider={dataProvider} layout={MyLayout}>
<Resource name="posts" {...posts} />
<CustomRoutes>
<Route path="/settings" element={<Settings />} />
<Route path="/profile" element={<Profile />} />
</CustomRoutes>
</Admin>
);
```

To learn more about custom menus, check [the `<Menu>` documentation](./Menu.md).

## Linking To Custom Routes

You can link to your pages using [react-router's Link component](https://reactrouter.com/en/main/components/link). Make sure to use the same value in the `<Link to>` prop as in the `<Route path>` prop.

```jsx
import { Link as RouterLink } from 'react-router-dom';
import { Link } from '@mui/material';

const SettingsButton = () => (
<Link component={RouterLink} to="/settings">
Settings
</Link>
);
```

## Sub-Routes

If you want to add sub-routes to a resource, add the `<Route>` elements as [children of the `<Resource>` element](./Resource.md#children):
Sometimes you want to add more routes to a resource path. For instance, you may want to add a custom page to the `/posts` resource, such as `/posts/analytics`.

To do so, add the `<Route>` elements as [children of the `<Resource>` element](./Resource.md#children):

```jsx
import { Admin, Resource } from 'react-admin';
import { Route } from "react-router-dom";

import dataProvider from './dataProvider';
import { dataProvider } from './dataProvider';
import posts from './posts';

const App = () => (
Expand Down
Binary file added docs/img/custom-route-nolayout.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/custom-route-title.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit b93c6a2

Please sign in to comment.