rare-sapphire
rare-sapphire3mo ago

Custom route provider

i build react refine ant design REST API , Nest project how to add custom route provider instead of default route in refine ant design project
20 Replies
kapa.ai
kapa.ai3mo ago
Hi @thilini. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To use a custom route provider in your Refine + Ant Design + REST API (NestJS) project, you need to implement your own router provider object and pass it to the <Refine /> component via the routerProvider prop. Refine is router-agnostic and supports custom router providers as long as they implement the required interface (methods like useHistory, useLocation, useParams, Prompt, Link, and optionally RouterComponent) Refine vs React-Admin: Routing. Here’s a high-level outline: 1. Create your custom router provider
Your provider should implement the required methods. For example:
const customRouterProvider = {
useHistory: () => ({
push: (path) => { /* your logic */ },
replace: (path) => { /* your logic */ },
goBack: () => { /* your logic */ },
}),
useLocation: () => ({
pathname: window.location.pathname,
search: window.location.search,
}),
useParams: () => {
// your logic to extract params
},
Prompt: (props) => { /* your Prompt component */ },
Link: (props) => <a {...props} />,
RouterComponent: ({ children }) => <>{children}</>,
};

const customRouterProvider = {
useHistory: () => ({
push: (path) => { /* your logic */ },
replace: (path) => { /* your logic */ },
goBack: () => { /* your logic */ },
}),
useLocation: () => ({
pathname: window.location.pathname,
search: window.location.search,
}),
useParams: () => {
// your logic to extract params
},
Prompt: (props) => { /* your Prompt component */ },
Link: (props) => <a {...props} />,
RouterComponent: ({ children }) => <>{children}</>,
};

2. Pass your custom provider to Refine
In your main app file, use your custom provider:
import { Refine } from "@refinedev/core";
import { RefineThemes, ThemedLayoutV2 } from "@refinedev/antd";
import dataProvider from "@refinedev/simple-rest";
import { App as AntdApp, ConfigProvider } from "antd";
import "@refinedev/antd/dist/reset.css";
export default function App() {
return (
<ConfigProvider theme={RefineThemes.Blue}>
<AntdApp>
<Refine
routerProvider={customRouterProvider}
dataProvider={dataProvider("<https://api.fake-rest.refine.dev">)}
resources={[
{
name: "products",
list: "/products",
},
]}
>
<ThemedLayoutV2>
{/* your routes/components */}
</ThemedLayoutV2>
</Refine>
</AntdApp>
</ConfigProvider>
);
}

import { Refine } from "@refinedev/core";
import { RefineThemes, ThemedLayoutV2 } from "@refinedev/antd";
import dataProvider from "@refinedev/simple-rest";
import { App as AntdApp, ConfigProvider } from "antd";
import "@refinedev/antd/dist/reset.css";
export default function App() {
return (
<ConfigProvider theme={RefineThemes.Blue}>
<AntdApp>
<Refine
routerProvider={customRouterProvider}
dataProvider={dataProvider("<https://api.fake-rest.refine.dev">)}
resources={[
{
name: "products",
list: "/products",
},
]}
>
<ThemedLayoutV2>
{/* your routes/components */}
</ThemedLayoutV2>
</Refine>
</AntdApp>
</ConfigProvider>
);
}

Note:
- You are responsible for implementing the navigation and route management logic in your custom provider. - Refine provides out-of-the-box router providers for React Router, Next.js, and others, but you can always supply your own as long as it matches the required interface Refine vs AdminBro: Routing, Routing Guide. If you need a reference for the required methods and structure, see the code snippets and explanations in the linked documentation above.
If you need more details on a specific router or integration, let me know! ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@1385106174310875166> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
rare-sapphire
rare-sapphireOP3mo ago
assume that sider bar blogpost menu wants navigate to create form instead of list , and after creating the new blogpost it must navigate to list it must have access default route of show,edit options also .. give example for that with project structure with codes @kapa.ai assume that sider bar blogpost menu wants navigate to create form instead of list , and after creating the new blogpost it must navigate to list it must have access default route of show,edit options also .. give example for that with project structure with codes
kapa.ai
kapa.ai3mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- To achieve the behavior where clicking the "Blog Posts" menu in the sidebar navigates directly to the create form (instead of the list), and after creating a new blog post, the app navigates to the list page, while still having access to the default show and edit routes, you need to: 1. Set the resource's list route to the create page (so the menu navigates to /blog-posts/create). 2. Ensure the create form redirects to the list after submission (default behavior). 3. Define the show and edit routes as usual. Below is an example project structure and code based on Refine with Ant Design and React Router, adapted from the official documentation and blog sources: --- Project Structure
src/
pages/
blog-posts/
create.tsx
edit.tsx
list.tsx
show.tsx
index.tsx
App.tsx
src/
pages/
blog-posts/
create.tsx
edit.tsx
list.tsx
show.tsx
index.tsx
App.tsx
--- src/pages/blog-posts/index.tsx
export * from "./create";
export * from "./edit";
export * from "./list";
export * from "./show";
export * from "./create";
export * from "./edit";
export * from "./list";
export * from "./show";
--- src/App.tsx
import { Refine, Authenticated } from "@refinedev/core";
import dataProvider from "@refinedev/simple-rest";
import routerProvider, { NavigateToResource } from "@refinedev/react-router";
import { BrowserRouter, Routes, Route, Outlet, Navigate } from "react-router";
import { ErrorComponent, RefineThemes, ThemedLayoutV2, useNotificationProvider } from "@refinedev/antd";
import { App as AntdApp, ConfigProvider } from "antd";
import "@refinedev/antd/dist/reset.css";

import { BlogPostList, BlogPostShow, BlogPostEdit, BlogPostCreate } from "./pages/blog-posts";
export default function App() {
return (
<BrowserRouter>
<ConfigProvider theme={RefineThemes.Blue}>
<AntdApp>
<Refine
routerProvider={routerProvider}
dataProvider={dataProvider("<https://api.fake-rest.refine.dev">)}
notificationProvider={useNotificationProvider}
resources={[
{
name: "blog-posts",
// Set list to the create page so the sidebar menu navigates to /blog-posts/create
list: "/blog-posts/create",
create: "/blog-posts/create",
edit: "/blog-posts/edit/:id",
show: "/blog-posts/show/:id",
},
]}
options={{ syncWithLocation: true }}
>
<Routes>
<Route
element={
<ThemedLayoutV2>
<Outlet />
</ThemedLayoutV2>
}
>
<Route path="/blog-posts">
{/* The menu will navigate here, which is the create form */}
<Route index element={<BlogPostCreate />} />
<Route path="create" element={<BlogPostCreate />} />
<Route path="edit/:id" element={<BlogPostEdit />} />
<Route path="show/:id" element={<BlogPostShow />} />
{/* Optionally, you can still expose the list page at a custom path */}
<Route path="list" element={<BlogPostList />} />
</Route>
<Route path="*" element={<ErrorComponent />} />
</Route>
</Routes>
</Refine>
</AntdApp>
</ConfigProvider>
</BrowserRouter>
);
}
import { Refine, Authenticated } from "@refinedev/core";
import dataProvider from "@refinedev/simple-rest";
import routerProvider, { NavigateToResource } from "@refinedev/react-router";
import { BrowserRouter, Routes, Route, Outlet, Navigate } from "react-router";
import { ErrorComponent, RefineThemes, ThemedLayoutV2, useNotificationProvider } from "@refinedev/antd";
import { App as AntdApp, ConfigProvider } from "antd";
import "@refinedev/antd/dist/reset.css";

import { BlogPostList, BlogPostShow, BlogPostEdit, BlogPostCreate } from "./pages/blog-posts";
export default function App() {
return (
<BrowserRouter>
<ConfigProvider theme={RefineThemes.Blue}>
<AntdApp>
<Refine
routerProvider={routerProvider}
dataProvider={dataProvider("<https://api.fake-rest.refine.dev">)}
notificationProvider={useNotificationProvider}
resources={[
{
name: "blog-posts",
// Set list to the create page so the sidebar menu navigates to /blog-posts/create
list: "/blog-posts/create",
create: "/blog-posts/create",
edit: "/blog-posts/edit/:id",
show: "/blog-posts/show/:id",
},
]}
options={{ syncWithLocation: true }}
>
<Routes>
<Route
element={
<ThemedLayoutV2>
<Outlet />
</ThemedLayoutV2>
}
>
<Route path="/blog-posts">
{/* The menu will navigate here, which is the create form */}
<Route index element={<BlogPostCreate />} />
<Route path="create" element={<BlogPostCreate />} />
<Route path="edit/:id" element={<BlogPostEdit />} />
<Route path="show/:id" element={<BlogPostShow />} />
{/* Optionally, you can still expose the list page at a custom path */}
<Route path="list" element={<BlogPostList />} />
</Route>
<Route path="*" element={<ErrorComponent />} />
</Route>
</Routes>
</Refine>
</AntdApp>
</ConfigProvider>
</BrowserRouter>
);
}
Key points: - The sidebar menu for "blog-posts" will now navigate to /blog-posts/create. - After creating a blog post, the default behavior of the create form is to redirect to the list page (/blog-posts). Since the list route is now the create page, you should add a dedicated list route (e.g., /blog-posts/list) and set the redirect target in your create form. --- src/pages/blog-posts/create.tsx
import { Create, useForm } from "@refinedev/antd";
import { useNavigation } from "@refinedev/core";

export const BlogPostCreate = () => {
const { formProps, saveButtonProps } = useForm({
// Redirect to the list page after creation
redirect: "list",
});

return (
<Create saveButtonProps={saveButtonProps}>
<Form {...formProps} layout="vertical">
<Form.Item label="Title" name="title" rules={[{ required: true }]}>
<Input />
</Form.Item>
{/* Add other fields as needed */}
</Form>
</Create>
);
};
import { Create, useForm } from "@refinedev/antd";
import { useNavigation } from "@refinedev/core";

export const BlogPostCreate = () => {
const { formProps, saveButtonProps } = useForm({
// Redirect to the list page after creation
redirect: "list",
});

return (
<Create saveButtonProps={saveButtonProps}>
<Form {...formProps} layout="vertical">
<Form.Item label="Title" name="title" rules={[{ required: true }]}>
<Input />
</Form.Item>
{/* Add other fields as needed */}
</Form>
</Create>
);
};
- The redirect: "list" option will redirect to /blog-posts after creation, but since /blog-posts is now the create page, you should use a custom redirect.
- To redirect to /blog-posts/list, use redirect: false and handle navigation manually:
import { useNavigation } from "@refinedev/core";
const { list } = useNavigation();

const { formProps, saveButtonProps } = useForm({
redirect: false,
onMutationSuccess: () => {
list("blog-posts", "list"); // navigates to /blog-posts/list
},
});
import { useNavigation } from "@refinedev/core";
const { list } = useNavigation();

const { formProps, saveButtonProps } = useForm({
redirect: false,
onMutationSuccess: () => {
list("blog-posts", "list"); // navigates to /blog-posts/list
},
});
See useForm redirect property
See useNavigation hook --- Accessing Show and Edit - The show and edit routes (/blog-posts/show/:id and /blog-posts/edit/:id) remain accessible and can be linked from the list or other components as usual. --- Summary:
- Set the resource's list route to the create page. - Add a dedicated list route (e.g., /blog-posts/list). - In the create form, redirect to the list route after creation. - Show and edit routes remain accessible. This approach is fully supported by Refine's flexible routing and resource configuration system, as shown in the documentation and blog examples Ant Design Integration Usage, useForm redirect, useNavigation. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3mo ago
<@1385106174310875166> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
rare-sapphire
rare-sapphireOP2mo ago
@kapa.ai give path for updated codes
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Based on the knowledge sources, here is how you can update your project to have the sidebar "blog-posts" menu navigate to the create form instead of the list, and after creating a new blog post, navigate to the list. You will also retain access to the default show and edit routes. Project Structure and Paths
src/
pages/
blog-posts/
create.tsx
edit.tsx
list.tsx
show.tsx
index.tsx
App.tsx
src/
pages/
blog-posts/
create.tsx
edit.tsx
list.tsx
show.tsx
index.tsx
App.tsx
1. src/pages/blog-posts/index.tsx
export * from "./create";
export * from "./edit";
export * from "./list";
export * from "./show";
export * from "./create";
export * from "./edit";
export * from "./list";
export * from "./show";
--- 2. src/App.tsx Update your resource and route definitions as follows:
import { Refine } from "@refinedev/core";
import dataProvider from "@refinedev/simple-rest";
import routerProvider, { NavigateToResource } from "@refinedev/react-router";
import { BrowserRouter, Routes, Route, Outlet } from "react-router-dom";
import { ErrorComponent, ThemedLayoutV2 } from "@refinedev/antd";
import { BlogPostList, BlogPostShow, BlogPostEdit, BlogPostCreate } from "./pages/blog-posts";
function App() {
return (
<BrowserRouter>
<Refine
routerProvider={routerProvider}
dataProvider={dataProvider("<https://api.fake-rest.refine.dev">)}
resources={[
{
name: "blog-posts",
// Set list to the create page so the sidebar menu navigates to /blog-posts/create
list: "/blog-posts/create",
create: "/blog-posts/create",
edit: "/blog-posts/edit/:id",
show: "/blog-posts/show/:id",
},
]}
>
<Routes>
<Route
element={
<ThemedLayoutV2>
<Outlet />
</ThemedLayoutV2>
}
>
<Route path="/blog-posts">
{/* The menu will navigate here, which is the create form */}
<Route index element={<BlogPostCreate />} />
<Route path="create" element={<BlogPostCreate />} />
<Route path="edit/:id" element={<BlogPostEdit />} />
<Route path="show/:id" element={<BlogPostShow />} />
{/* Optionally, expose the list page at a custom path */}
<Route path="list" element={<BlogPostList />} />
</Route>
<Route path="*" element={<ErrorComponent />} />
</Route>
</Routes>
</Refine>
</BrowserRouter>
);
}

export default App;
import { Refine } from "@refinedev/core";
import dataProvider from "@refinedev/simple-rest";
import routerProvider, { NavigateToResource } from "@refinedev/react-router";
import { BrowserRouter, Routes, Route, Outlet } from "react-router-dom";
import { ErrorComponent, ThemedLayoutV2 } from "@refinedev/antd";
import { BlogPostList, BlogPostShow, BlogPostEdit, BlogPostCreate } from "./pages/blog-posts";
function App() {
return (
<BrowserRouter>
<Refine
routerProvider={routerProvider}
dataProvider={dataProvider("<https://api.fake-rest.refine.dev">)}
resources={[
{
name: "blog-posts",
// Set list to the create page so the sidebar menu navigates to /blog-posts/create
list: "/blog-posts/create",
create: "/blog-posts/create",
edit: "/blog-posts/edit/:id",
show: "/blog-posts/show/:id",
},
]}
>
<Routes>
<Route
element={
<ThemedLayoutV2>
<Outlet />
</ThemedLayoutV2>
}
>
<Route path="/blog-posts">
{/* The menu will navigate here, which is the create form */}
<Route index element={<BlogPostCreate />} />
<Route path="create" element={<BlogPostCreate />} />
<Route path="edit/:id" element={<BlogPostEdit />} />
<Route path="show/:id" element={<BlogPostShow />} />
{/* Optionally, expose the list page at a custom path */}
<Route path="list" element={<BlogPostList />} />
</Route>
<Route path="*" element={<ErrorComponent />} />
</Route>
</Routes>
</Refine>
</BrowserRouter>
);
}

export default App;
This approach is consistent with the routing and resource configuration patterns shown in the official documentation and blog posts see example. --- 3. src/pages/blog-posts/create.tsx To redirect to the list after creation, you can use the redirect property or handle navigation manually. Here is a simple example using the redirect property:
import { Create, useForm } from "@refinedev/antd";
import { Form, Input } from "antd";

export const BlogPostCreate = () => {
const { formProps, saveButtonProps } = useForm({
redirect: "/blog-posts/list", // Redirect to the list page after creation
});

return (
<Create saveButtonProps={saveButtonProps}>
<Form {...formProps} layout="vertical">
<Form.Item label="Title" name="title" rules={[{ required: true }]}>
<Input />
</Form.Item>
{/* Add other fields as needed */}
</Form>
</Create>
);
};
import { Create, useForm } from "@refinedev/antd";
import { Form, Input } from "antd";

export const BlogPostCreate = () => {
const { formProps, saveButtonProps } = useForm({
redirect: "/blog-posts/list", // Redirect to the list page after creation
});

return (
<Create saveButtonProps={saveButtonProps}>
<Form {...formProps} layout="vertical">
<Form.Item label="Title" name="title" rules={[{ required: true }]}>
<Input />
</Form.Item>
{/* Add other fields as needed */}
</Form>
</Create>
);
};
This pattern is supported by the useForm redirect property. --- 4. Show and Edit Pages Your show and edit pages remain accessible at /blog-posts/show/:id and /blog-posts/edit/:id as defined in your routes and resources. --- Summary of updated paths: - Sidebar "blog-posts" menu: /blog-posts (renders create form) - Create form: /blog-posts/create - List page: /blog-posts/list - Show page: /blog-posts/show/:id - Edit page: /blog-posts/edit/:id This setup ensures the sidebar navigates to the create form, and after creation, users are redirected to the list, while still having access to show and edit routes as per Refine's routing and resource configuration best practices source. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@1385106174310875166> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
rare-sapphire
rare-sapphireOP2mo ago
@kapa.ai that create page default left arrow dont navigate to list page why? import { Create, useForm, useSelect } from "@refinedev/antd"; import MDEditor from "@uiw/react-md-editor"; import { Form, Input, Select } from "antd"; export const BlogPostCreate = () => { const { formProps, saveButtonProps } = useForm({ redirect: "list", }); const { selectProps: categorySelectProps } = useSelect({ resource: "categories", }); return ( <Create saveButtonProps={saveButtonProps}> <Form {...formProps} layout="vertical"> <Form.Item label={"Title"} name={["title"]} rules={[ { required: true, }, ]} > <Input /> </Form.Item> <Form.Item label={"Content"} name="content" rules={[ { required: true, }, ]} > <MDEditor data-color-mode="light" /> </Form.Item> <Form.Item label={"Category"} name={["category", "id"]} rules={[ { required: true, }, ]} > <Select {...categorySelectProps} /> </Form.Item> <Form.Item label={"Status"} name={["status"]} initialValue={"draft"} rules={[ { required: true, }, ]} > <Select defaultValue={"draft"} options={[ { value: "draft", label: "Draft" }, { value: "published", label: "Published" }, { value: "rejected", label: "Rejected" }, ]} style={{ width: 120 }} /> </Form.Item> </Form> </Create> ); };
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- The default left arrow (back button) in the <Create /> page does not navigate to the list page if your route does not have an :action parameter or if your action is list. In this case, even if you pass a goBack property, the back button will not be shown or will not behave as expected. This is explicitly mentioned in the documentation:
If your route has no :action parameter or your action is list, the back button will not be shown even if you pass a goBack property. You can override this behavior by using the headerProps property
Ant Design Create Properties. If you want the back button to always navigate to the list page, you should override the default behavior by providing a custom back button and handling the navigation yourself, for example:
import { useNavigation } from "@refinedev/core";
import { Button } from "antd";

const { list } = useNavigation();
const BackButton = () => (
<Button onClick={() => list("blog-posts", "list")}>←</Button>
);

<Create goBack={<BackButton />} headerProps={{ onBack: () => list("blog-posts", "list") }}>
{/* ... */}
</Create>
import { useNavigation } from "@refinedev/core";
import { Button } from "antd";

const { list } = useNavigation();
const BackButton = () => (
<Button onClick={() => list("blog-posts", "list")}>←</Button>
);

<Create goBack={<BackButton />} headerProps={{ onBack: () => list("blog-posts", "list") }}>
{/* ... */}
</Create>
This ensures the back button always navigates to your desired list page, regardless of the current route structure or action parameter
Ant Design Create goBack. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@1385106174310875166> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
rare-sapphire
rare-sapphireOP2mo ago
@kapa.ai update this code --> import { Create, useForm } from "@refinedev/antd"; import { Form, Input } from "antd"; import { useNavigation } from "@refinedev/core"; import { Button } from "antd"; const { list } = useNavigation(); const BackButton = () => ( <Button onClick={() => list("blog-posts", "list")}>←</Button> ); export const CategoryCreate = () => { const { formProps, saveButtonProps } = useForm({ redirect: "list", }); return ( <Create saveButtonProps={saveButtonProps}> <Form {...formProps} layout="vertical"> <Form.Item label={"Title"} name={["title"]} rules={[ { required: true, }, ]} > <Input /> </Form.Item> </Form> </Create>
); };
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- Here is the updated code to ensure the back button in the <Create /> page always navigates to the list page. According to the documentation, you should use the goBack prop and, if needed, the headerProps to override the default behavior and ensure the button is shown and works as expected, even if your route does not have an :action parameter or your action is list see documentation:
import { Create, useForm } from "@refinedev/antd";
import { Form, Input, Button } from "antd";
import { useNavigation } from "@refinedev/core";

export const CategoryCreate = () => {
const { list } = useNavigation();

const { formProps, saveButtonProps } = useForm({
redirect: "list",
});

// Custom back button that navigates to the list page
const BackButton = () => (
<Button onClick={() => list("blog-posts", "list")}>←</Button>
);

return (
<Create
saveButtonProps={saveButtonProps}
goBack={<BackButton />}
headerProps={{ onBack: () => list("blog-posts", "list") }}
>
<Form {...formProps} layout="vertical">
<Form.Item
label={"Title"}
name={["title"]}
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
</Form>
</Create>
);
};
import { Create, useForm } from "@refinedev/antd";
import { Form, Input, Button } from "antd";
import { useNavigation } from "@refinedev/core";

export const CategoryCreate = () => {
const { list } = useNavigation();

const { formProps, saveButtonProps } = useForm({
redirect: "list",
});

// Custom back button that navigates to the list page
const BackButton = () => (
<Button onClick={() => list("blog-posts", "list")}>←</Button>
);

return (
<Create
saveButtonProps={saveButtonProps}
goBack={<BackButton />}
headerProps={{ onBack: () => list("blog-posts", "list") }}
>
<Form {...formProps} layout="vertical">
<Form.Item
label={"Title"}
name={["title"]}
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
</Form>
</Create>
);
};
This approach follows the recommended pattern for customizing the back button in Refine's Ant Design integration, ensuring it always navigates to the list page regardless of the route structure source. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@1385106174310875166> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
rare-sapphire
rare-sapphireOP2mo ago
@kapa.ai Argument of type '"list"' is not assignable to parameter of type 'HistoryType | undefined'.ts(2345) , got that error
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- The error occurs because the second argument of the list method from useNavigation is expected to be a HistoryType ("push" or "replace"), not a custom string like "list". The "list" value is not valid for this parameter, which is why TypeScript complains. According to the documentation, the correct usage is:
list("blog-posts"); // navigates to the /blog-posts page
list("blog-posts"); // navigates to the /blog-posts page
If you want to navigate to a custom list route (e.g., /blog-posts/list), you should ensure your resource and route configuration matches, or use the push method for custom paths. Corrected code:
import { Create, useForm } from "@refinedev/antd";
import { Form, Input, Button } from "antd";
import { useNavigation } from "@refinedev/core";

export const CategoryCreate = () => {
const { list, push } = useNavigation();

const { formProps, saveButtonProps } = useForm({
redirect: false, // We'll handle redirect manually
onMutationSuccess: () => {
push("/blog-posts/list"); // Navigate to the custom list page after create
},
});

// Custom back button that navigates to the list page
const BackButton = () => (
<Button onClick={() => push("/blog-posts/list")}>←</Button>
);

return (
<Create
saveButtonProps={saveButtonProps}
goBack={<BackButton />}
headerProps={{ onBack: () => push("/blog-posts/list") }}
>
<Form {...formProps} layout="vertical">
<Form.Item
label={"Title"}
name={["title"]}
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
</Form>
</Create>
);
};
import { Create, useForm } from "@refinedev/antd";
import { Form, Input, Button } from "antd";
import { useNavigation } from "@refinedev/core";

export const CategoryCreate = () => {
const { list, push } = useNavigation();

const { formProps, saveButtonProps } = useForm({
redirect: false, // We'll handle redirect manually
onMutationSuccess: () => {
push("/blog-posts/list"); // Navigate to the custom list page after create
},
});

// Custom back button that navigates to the list page
const BackButton = () => (
<Button onClick={() => push("/blog-posts/list")}>←</Button>
);

return (
<Create
saveButtonProps={saveButtonProps}
goBack={<BackButton />}
headerProps={{ onBack: () => push("/blog-posts/list") }}
>
<Form {...formProps} layout="vertical">
<Form.Item
label={"Title"}
name={["title"]}
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
</Form>
</Create>
);
};
Summary:
- Use push("/blog-posts/list") to navigate to a custom list route. - The list method only accepts the resource name and an optional HistoryType ("push" or "replace"), not a custom string like "list" see documentation. If you want to use the default list route (e.g., /blog-posts), you can simply use list("blog-posts"). If you have a custom list route, use push with the full path. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@1385106174310875166> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
rare-sapphire
rare-sapphireOP2mo ago
@kapa.ai but still not working cant acess the list page by using back navigation
kapa.ai
kapa.ai2mo ago
Let me check the knowledge base for you again. One moment! :books: ---------------------- You're correct—if you set your resource's list route to the create page (e.g., list: "/blog-posts/create"), the default back navigation (left arrow) on the create page will not take you to the list page, because Refine's routing logic assumes the "list" action is at /blog-posts, but in your setup, that's now the create page. This is a limitation of how Refine's resource and routing system works: the back button tries to go to the resource's list route, which in your case is the create page itself, causing a loop or unexpected behavior. The official documentation states:
If your route has no :action parameter or your action is list, the back button will not be shown even if you pass a goBack property. You can override this behavior by using the headerProps property
Ant Design Create Properties. However, even with headerProps={{ onBack: ... }} and a custom goBack button, if your resource's list route is not a real list page, you will not be able to access the list page via the default navigation logic. Workaround:
- You must define a dedicated list route (e.g., /blog-posts/list) and ensure your sidebar/menu links to that path directly, instead of relying on the resource's list property. - Use the push("/blog-posts/list") method in your custom back button and in headerProps.onBack to ensure navigation works as expected. But:
If your sidebar is generated by Refine from the resources array, it will always use the list property for navigation. If you set list: "/blog-posts/list", then the menu will go to the list page, not the create page. Summary:
- With Refine's current routing and resource system, you cannot have the sidebar menu go to the create page and also have the default back navigation on the create page go to the list page, unless you manually manage both the menu and the navigation logic. - This is a limitation of the resource-based routing system as described in the documentation.
- If you need both behaviors, you must customize your sidebar/menu and navigation logic, and not rely solely on the resources array for menu generation and navigation. If you need a fully custom navigation experience, you will need to build your own sidebar and navigation logic, rather than relying on Refine's automatic resource-based menu and routing. If you need more advanced routing, the knowledge sources do not provide a built-in solution for this scenario. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2mo ago
<@1385106174310875166> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?