Skip to main content

Defining Resources

So far, we've integrated the authentication logic into our routes. In this step, we'll be creating routes for these components and define our resources to inform Refine about their corresponding routes.

To learn more about it, please refer to the Resource Concept section in the General Concepts guide.

Creating Routes

We've wrapped our routes with the <Authenticated /> component in the previous step. Now we'll be creating routes under the /products path to place our components. We'll use the following routes to place our components:

  • /products - <ListProducts />
  • /products/:id - <ShowProduct />
  • /products/:id/edit - <EditProduct />
  • /products/create - <CreateProduct />

We'll also be defining an index route at / and redirecting it to /products using the <Navigate /> component.

Update your src/App.tsx file by adding the following lines:

src/App.tsx
import { Refine, Authenticated } from "@refinedev/core";
import routerProvider from "@refinedev/react-router-v6";

import {
BrowserRouter,
Routes,
Route,
Outlet,
Navigate,
} from "react-router-dom";

import { dataProvider } from "./providers/data-provider";
import { authProvider } from "./providers/auth-provider";

import { ShowProduct } from "./pages/products/show";
import { EditProduct } from "./pages/products/edit";
import { ListProducts } from "./pages/products/list";
import { CreateProduct } from "./pages/products/create";

import { Login } from "./pages/login";
import { Header } from "./components/header";

export default function App(): JSX.Element {
return (
<BrowserRouter>
<Refine
dataProvider={dataProvider}
authProvider={authProvider}
routerProvider={routerProvider}
>
<Routes>
<Route
element={
<Authenticated key="authenticated-routes" redirectOnFail="/login">
<Header />
<Outlet />
</Authenticated>
}
>
<Route index element={<Navigate to="/products" />} />
<Route path="/products">
<Route index element={<ListProducts />} />
<Route path=":id" element={<ShowProduct />} />
<Route path=":id/edit" element={<EditProduct />} />
<Route path="create" element={<CreateProduct />} />
</Route>
</Route>
<Route
element={
<Authenticated key="auth-pages" fallback={<Outlet />}>
<Navigate to="/products" />
</Authenticated>
}
>
<Route path="/login" element={<Login />} />
</Route>
</Routes>
</Refine>
</BrowserRouter>
);
}

Defining Resources

Now we've created our routes, it's time to define our resources. This will allow Refine to know about our resources and treat them accordingly.

While defining the resources and assigning appropriate routes to actions is optional, it's highly recommended to do so in order to take advantage of Refine's provided features below.

By defining our resources, we'll be unlocking the following features:

  • Inferring the related parameters from the routes without the need to pass them explicitly.
  • Handling redirections automatically and handling navigations between these routes easily.
  • Easily creating menus and breadcrumbs for our resources.
  • Ability to pass meta values to every data hook per resource from a single place.
  • Easily managing features like access control, i18n, and more.

We'll be using the resources prop of the <Refine /> component to define our resources.

A resource definition consists of the following properties:

  • name: The name of the resource. This will be passed to the data provider's methods to identify the resource.
  • identifier: An optional identifier for the resource. If not provided, name will be used as the identifier. This is useful when you want to use the same resource for the data provider but have a different configuration on Refine's side.
  • list, create, edit and show: These properties are used to define the routes for the corresponding actions. They will be the string values of the routes we've created in the previous step.
  • meta: An optional object to pass meta values per resource. This is widely used in Refine's hooks and components for various purposes from data fetching, access control, i18n to UI customization.

Update your src/App.tsx file by adding the following lines:

src/App.tsx
import { Refine, Authenticated } from "@refinedev/core";
import routerProvider, { NavigateToResource } from "@refinedev/react-router-v6";

import { BrowserRouter, Routes, Route, Outlet } from "react-router-dom";

import { dataProvider } from "./providers/data-provider";
import { authProvider } from "./providers/auth-provider";

import { ShowProduct } from "./pages/products/show";
import { EditProduct } from "./pages/products/edit";
import { ListProducts } from "./pages/products/list";
import { CreateProduct } from "./pages/products/create";

import { Login } from "./pages/login";
import { Header } from "./components/header";

export default function App(): JSX.Element {
return (
<BrowserRouter>
<Refine
dataProvider={dataProvider}
authProvider={authProvider}
routerProvider={routerProvider}
resources={[
{
name: "protected-products",
list: "/products",
show: "/products/:id",
edit: "/products/:id/edit",
create: "/products/create",
meta: { label: "Products" },
},
]}
>
<Routes>
<Route
element={
<Authenticated key="authenticated-routes" redirectOnFail="/login">
<Header />
<Outlet />
</Authenticated>
}
>
<Route
index
// We're also replacing the <Navigate /> component with the <NavigateToResource /> component.
// It's tailored version of the <Navigate /> component that will redirect to the resource's list route.
element={<NavigateToResource resource="protected-products" />}
/>
<Route path="/products">
<Route index element={<ListProducts />} />
<Route path=":id" element={<ShowProduct />} />
<Route path=":id/edit" element={<EditProduct />} />
<Route path="create" element={<CreateProduct />} />
</Route>
</Route>
<Route
element={
<Authenticated key="auth-pages" fallback={<Outlet />}>
{/* We're also replacing the <Navigate /> component with the <NavigateToResource /> component. */}
{/* It's tailored version of the <Navigate /> component that will redirect to the resource's list route. */}
<NavigateToResource resource="protected-products" />
</Authenticated>
}
>
<Route path="/login" element={<Login />} />
</Route>
</Routes>
</Refine>
</BrowserRouter>
);
}

Now we've defined our routes and resources, we're ready to start refactoring our components to benefit from the features provided by Refine.

In the next step, we'll be learning about the navigation helpers of Refine and how to use them.

Was this helpful?
import { Refine, Authenticated } from "@refinedev/core";
import routerProvider from "@refinedev/react-router-v6";

import {
  BrowserRouter,
  Routes,
  Route,
  Outlet,
  Navigate,
} from "react-router-dom";

import { dataProvider } from "./providers/data-provider";
import { authProvider } from "./providers/auth-provider";

import { ShowProduct } from "./pages/products/show";
import { EditProduct } from "./pages/products/edit";
import { ListProducts } from "./pages/products/list";
import { CreateProduct } from "./pages/products/create";

import { Login } from "./pages/login";
import { Header } from "./components/header";

export default function App(): JSX.Element {
  return (
    <BrowserRouter>
      <Refine
        dataProvider={dataProvider}
        authProvider={authProvider}
        routerProvider={routerProvider}
      >
        <Routes>
          <Route
            element={
              // We're wrapping our routes with the `<Authenticated />` component
              // We're omitting the `fallback` prop to redirect users to the login page if they are not authenticated.
              // If the user is authenticated, we'll render the `<Header />` component and the `<Outlet />` component to render the inner routes.
              <Authenticated key="authenticated-routes" redirectOnFail="/login">
                <Header />
                <Outlet />
              </Authenticated>
            }
          >
            <Route index element={<ListProducts />} />
          </Route>
          <Route
            element={
              <Authenticated key="auth-pages" fallback={<Outlet />}>
                {/* We're redirecting the user to "/" if they are authenticated and trying to access the "/login" route */}
                <Navigate to="/" />
              </Authenticated>
            }
          >
            <Route path="/login" element={<Login />} />
          </Route>
        </Routes>
      </Refine>
    </BrowserRouter>
  );
}
installing dependencies
installing dependencies