Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@refinedev/core

refinedev135.5kMIT4.57.9TypeScript support: included

Refine is a React meta-framework for building enterprise-level, data-intensive applications rapidly with support for modern UI libraries and headless integrations.

readme



The sweet spot between the low/no code and “starting from scratch” for CRUD-heavy applications.
Refine is as an open source, React meta-framework for enterprise. It provides a headless solution for everything from admin panels to dashboards and internal tools.

Awesome OpenSSF Best Practices npm version Contributor Covenant

Discord Twitter Follow


how-refine-works

What is Refine?

Refine is a React meta-framework for CRUD-heavy web applications. It addresses a wide range of enterprise use cases including internal tools, admin panels, dashboards and B2B apps.

Refine's core hooks and components streamline the development process by offering industry-standard solutions for crucial aspects of a project, including authentication, access control, routing, networking, state management, and i18n.

Refine's headless architecture enables the building of highly customizable applications by decoupling business logic from UI and routing. This allows integration with:

  • Any custom designs or UI frameworks like TailwindCSS, along with built-in support for Ant Design, Material UI, Mantine, and Chakra UI.

  • Various platforms, including Next.js, Remix, React Native, Electron, etc., by a simple routing interface without the need for additional setup steps.

⚡ Try Refine

Start a new project with Refine in seconds using the following command:

npm create refine-app@latest my-refine-app

Or you can create a new project on your browser:

Quick Start

Here's Refine in action, the below code is an example of a simple CRUD application using Refine + React Router + Material UI:

import React from "react";
import { Refine, useMany } from "@refinedev/core";
import { ThemedLayoutV2 } from "@refinedev/mui";
import dataProvider from "@refinedev/simple-rest";
import routerProvider from "@refinedev/react-router";
import { BrowserRouter, Outlet, Route, Routes } from "react-router";

import CssBaseline from "@mui/material/CssBaseline";

export default function App() {
  return (
    <BrowserRouter>
      <CssBaseline />
      <Refine
        dataProvider={dataProvider("https://api.fake-rest.refine.dev")}
        routerProvider={routerProvider}
        resources={[
          {
            name: "products",
            list: "/products",
          },
        ]}
      >
        <Routes>
          <Route
            element={
              <ThemedLayoutV2>
                <Outlet />
              </ThemedLayoutV2>
            }
          >
            <Route path="/products">
              <Route index element={<ProductList />} />
            </Route>
          </Route>
        </Routes>
      </Refine>
    </BrowserRouter>
  );
}

// src/pages/products/list.tsx

import { List, useDataGrid, DateField } from "@refinedev/mui";
import { DataGrid, GridColDef } from "@mui/x-data-grid";

export const ProductList = () => {
  const { dataGridProps } = useDataGrid();

  const { data: categories, isLoading } = useMany({
    resource: "categories",
    ids:
      dataGridProps?.rows?.map((item) => item?.category?.id).filter(Boolean) ??
      [],
    queryOptions: {
      enabled: !!dataGridProps?.rows,
    },
  });

  const columns = React.useMemo<GridColDef[]>(
    () => [
      { field: "id", headerName: "ID", type: "number" },
      { field: "name", flex: 1, headerName: "Name" },
      {
        field: "category",
        flex: 1,
        headerName: "Category",
        display: "flex",
        renderCell: ({ value }) =>
          isLoading
            ? "Loading..."
            : categories?.data?.find((item) => item.id === value?.id)?.title,
      },
      {
        field: "createdAt",
        flex: 1,
        headerName: "Created at",
        display: "flex",
        renderCell: ({ value }) => <DateField value={value} />,
      },
    ],
    [categories?.data, isLoading],
  );

  return (
    <List>
      <DataGrid {...dataGridProps} columns={columns} />
    </List>
  );
};

The result will look like this:

Refine + Material UI Example

Use cases

Refine shines on data-intensive⚡ enterprise B2B applications like admin panels, dashboards and internal tools. Thanks to the built-in SSR support, it can also power customer-facing applications like storefronts.

You can take a look at some live examples that can be built using Refine from scratch:

Key Features

  • Refine Devtools - dive deeper into your app and provide useful insights
  • Connectors for 15+ backend services including REST API, GraphQL, NestJs CRUD, Airtable, Strapi, Strapi v4, Supabase, Hasura, Appwrite, Nestjs-Query, Firebase, Sanity, and Directus.
  • SSR support with Next.js & Remix and Advanced routing with any router library of your choice
  • Auto-generation of CRUD UIs based on your API data structure
  • Perfect state management & mutations with React Query
  • Providers for seamless authentication and access control flows
  • Out-of-the-box support for live / real-time applications
  • Easy audit logs & document versioning

Learning Refine

  • Navigate to the Tutorial on building comprehensive CRUD application guides you through each step of the process.
  • Visit the Guides & Concepts to get informed about the fundamental concepts.
  • Read more on Advanced Tutorials for different usage scenarios.

Contribution

Refer to the contribution docs for more information.

If you have any doubts related to the project or want to discuss something, then join our Discord server.

Contributors ♥️ Thanks

We extend our gratitude to all our numerous contributors who create plugins, assist with issues and pull requests, and respond to questions on Discord and GitHub Discussions.

Refine is a community-driven project, and your contributions continually improve it.


License

Licensed under the MIT License, Copyright © 2021-present Refinedev

changelog

@refinedev/core

4.57.9

Patch Changes

📢 Refine Community Release 📢

  • fix: wrong JSDoc links in components

4.57.8

Patch Changes

Refine Enterprise Release

4.57.7

Patch Changes

📢 Refine Community Release 📢

  • Move invalidation in useRegister to be called only on success.

    Resolves #6639

📢 Refine Community Release 📢

  • fix(types): remove path aliases from type imports

    Since typescript doesn't resolve and replace path aliases, using them for the type imports will cause d.ts files to reference unresolvable paths and types.

    While this doesn't break everything, it breaks the types in places where the path aliases are used for type imports.

    This change removes the path aliases from the type imports and replaces them with relative imports.

4.57.6

Patch Changes

Refine Enterprise Release

Refine Enterprise Release

  • #6683 a12a0821e3c573386c2a8eea4ac1582cc46dd26d Thanks @aliemir! - fix(types): remove path aliases from type imports

    Since typescript doesn't resolve and replace path aliases, using them for the type imports will cause d.ts files to reference unresolvable paths and types.

    While this doesn't break everything, it breaks the types in places where the path aliases are used for type imports.

    This change removes the path aliases from the type imports and replaces them with relative imports.

4.57.5

Patch Changes

📢 Refine Community Release 📢

  • feat(core): add enabled prop to useLoadingOvertime and overtimeOptions

    Added missing enabled prop to useLoadingOvertime and added ability to globally configure through options.overtime.enabled.

    Due to the nature of calculating elapsed time, an interval is set by the interval prop. This was causing unwanted updates in the return value and there was no way to disable it properly.

📢 Refine Community Release 📢

  • fixed: to query parameter is not working after login. #6582 From now on, the to query parameter will work after login. If the URL includes a to query parameter, the user will be redirected to the specified path after logging in.

    Example:

    After logout, Refine will automatically appends to query param to URL.

    http://localhost:3000/login?to=/any-path

    After login, it will redirect to http://localhost:3000/any-path

    Resolves #6582

📢 Refine Community Release 📢

  • refactor(core): remove duplicated overtime intervals caused by internally used hooks

    Updated Refine's data hooks and extensions to prevent duplicated overtime intervals from being created. This uses the enabled prop to prevent internal hooks from registering the intervals.

    Prior to this change, useTable was initializing its own useLoadingOvertime hook but also propagated the elapsedTime from useList hook which is used internally by useTable. This caused duplicated intervals and unwanted updates.

    This now ensures a single interval is created and used for the extension hooks.

📢 Refine Community Release 📢

  • fix(core): add missing checks and warnings for ids and resource props in useMany hook

    Added checks for ids and resource props to check in runtime if they are valid or not.

    useMany will warn if ids or resource props are missing unless the query is manually enabled through queryOptions.enabled prop.

    Resolves #6617

4.57.4

Patch Changes

Refine Enterprise Release

  • #6626 087039f0ccd13e9fe5bf4ef904e4f1c2df129d69 Thanks @aliemir! - feat(core): add enabled prop to useLoadingOvertime and overtimeOptions

    Added missing enabled prop to useLoadingOvertime and added ability to globally configure through options.overtime.enabled.

    Due to the nature of calculating elapsed time, an interval is set by the interval prop. This was causing unwanted updates in the return value and there was no way to disable it properly.

Refine Enterprise Release

  • #6626 087039f0ccd13e9fe5bf4ef904e4f1c2df129d69 Thanks @aliemir! - refactor(core): remove duplicated overtime intervals caused by internally used hooks

    Updated Refine's data hooks and extensions to prevent duplicated overtime intervals from being created. This uses the enabled prop to prevent internal hooks from registering the intervals.

    Prior to this change, useTable was initializing its own useLoadingOvertime hook but also propagated the elapsedTime from useList hook which is used internally by useTable. This caused duplicated intervals and unwanted updates.

    This now ensures a single interval is created and used for the extension hooks.

4.57.3

Patch Changes

Refine Enterprise Release

  • #6618 5377e7d8f7ccb986c5d38352351b9b2d2c414fde Thanks @aliemir! - fix(core): add missing checks and warnings for ids and resource props in useMany hook

    Added checks for ids and resource props to check in runtime if they are valid or not.

    useMany will warn if ids or resource props are missing unless the query is manually enabled through queryOptions.enabled prop.

    Resolves #6617

4.57.2

Patch Changes

Refine Enterprise Release

  • #6583 5ce59d0352ba5402452bb812ac0e506b3c2216df Thanks @alicanerdurmaz! - fixed: to query parameter is not working after login. #6582 From now on, the to query parameter will work after login. If the URL includes a to query parameter, the user will be redirected to the specified path after logging in.

    Example:

    After logout, Refine will automatically appends to query param to URL.

    http://localhost:3000/login?to=/any-path

    After login, it will redirect to http://localhost:3000/any-path

    Resolves #6582

4.57.1

Patch Changes

📢 Refine Community Release 📢

  • This PR fixes an issue where the ListButton component doesn't include a query filter in the navigation URL.

    Resolves #6528

📢 Refine Community Release 📢

  • chore: update package descriptions

📢 Refine Community Release 📢

  • refactor: modified the Authenticated component to receive optional params prop to be passed to the useIsAuthenticated hook.

    Fixes #6309

📢 Refine Community Release 📢

  • fix: useUpdate and useForm hooks throws an error when id is an empty string. (id="") #6505

    This reverts a breaking change introduced in PR #6116 and restores support for using an empty string as id. This enables updates without an id field, as allowed before @refinedev/core@4.54.0.

    Affected versions with this bug:

    • @refinedev/core@4.54.0
    • @refinedev/core@4.54.1
    • @refinedev/core@4.55.0
    • @refinedev/core@4.56.0

    The bug is fixed in:

    • @refinedev/core@4.56.1

    Resolves #6505

  • Updated dependencies []:

4.57.0

Minor Changes

Refine Enterprise Release

Refine Enterprise Release

Patch Changes

Refine Enterprise Release

Refine Enterprise Release

4.56.0

Minor Changes

  • #6445 4ff4335274d5689ec62127312695b76d692a125a Thanks @alicanerdurmaz! - feat: added new prop called mutationVariables to <AuthPage />. #6431 From now on, you can pass additional parameters to the authProvider methods using the mutationVariables prop of the <AuthPage /> component.

    import { AuthPage } from "@refinedev/antd"; // or "@refinedev/chakra-ui", "@refinedev/mantine", "@refinedev/mui"
    
    const MyLoginPage = () => {
      return (
        <AuthPage
          type="login" // all other types are also supported.
          // highlight-start
          mutationVariables={{
            foo: "bar",
            xyz: "abc",
          }}
          // highlight-end
        />
      );
    };
    
    // all mutation methods are supported.
    const authProvider = {
      login: async ({ foo, xyz, ...otherProps }) => {
        console.log(foo); // bar
        console.log(xyz); // abc
        // ...
      },
      register: async ({ foo, xyz, ...otherProps }) => {
        console.log(foo); // bar
        console.log(xyz); // abc
        // ...
      },
      // ...
    };

    Resolves #6431

  • #6445 4ff4335274d5689ec62127312695b76d692a125a Thanks @alicanerdurmaz! - feat: exported useInvalidateAuthStore hook from auth hooks

    Now you can invalide the users identity state and force a react query refresh using this hook

    Resolves #6341

  • #6445 4ff4335274d5689ec62127312695b76d692a125a Thanks @alicanerdurmaz! - feat: Added MetaContext to share data between components, providers, and hooks.

    🚨 Designed for internal use only.

Patch Changes

  • #6445 4ff4335274d5689ec62127312695b76d692a125a Thanks @alicanerdurmaz! - fix: Added more flexibility to the <Link /> component's ref type by changing it from HTMLAnchorElement to Element. From now on, we can pass any type of ref to the <Link /> component.

    // Before fix - Only worked with HTMLAnchorElement
    const ref = useRef<HTMLAnchorElement>(null);
    
    // After fix - Works with any Element type
    const ref = useRef<HTMLDivElement>(null);
    const ref = useRef<HTMLSpanElement>(null);

    Resolves #6463

  • #6445 4ff4335274d5689ec62127312695b76d692a125a Thanks @alicanerdurmaz! - fix: Priority logic between to and go props in Link component. From now on, the to prop has priority over the go prop. If both are passed, the to prop will be used.

    // Before fix - go would override to
    <Link to="/posts" go={{ resource: "categories" }} />
    
    // After fix - to overrides go
    <Link to="/posts" go={{ resource: "categories" }} />

    Resolves #6461

4.55.0

Minor Changes

  • #6330 5a81b35bc1eedbecb4b6c531a2fa5235dd0caf31 Thanks @alicanerdurmaz! - feat: add <Link /> component to navigate to a resource with a specific action. Under the hood, It uses useGo to generate the URL.

    Usage

    import { Link } from "@refinedev/core";
    
    const MyComponent = () => {
      return (
        <>
          {/* simple usage, navigates to `/posts` */}
          <Link to="/posts">Posts</Link>
          {/* complex usage with more control, navigates to `/posts` with query filters */}
          <Link
            go={{
              query: {
                // `useTable` or `useDataGrid` automatically use this filters to fetch data if `syncWithLocation` is true.
                filters: [
                  {
                    operator: "eq",
                    value: "published",
                    field: "status",
                  },
                ],
              },
              to: {
                resource: "posts",
                action: "list",
              },
            }}
          >
            Posts
          </Link>
        </>
      );
    };

    Fixes #6329

  • #6330 5a81b35bc1eedbecb4b6c531a2fa5235dd0caf31 Thanks @alicanerdurmaz! - chore: From now on, useLink returns <Link /> component instead of returning routerProvider.Link.

    Since the <Link /> component uses routerProvider.Link under the hood with leveraging useGo hook to generate the URL there is no breaking change. It's recommended to use the <Link /> component from the @refinedev/core package instead of useLink hook. This hook is used mostly for internal purposes and is only exposed for customization needs.

    Fixes #6329

Patch Changes

  • #6327 c630b090539082b5166b508053f87274624c794e Thanks @Anonymous961! - fix(core): added ability to return undefined to fallback to the default notification config when using the function form in successNotification and errorNotification props.

    Resolves #6270

  • #6353 a0f2d7bbef3093e11c3024bb7fa2a0ffc3ce9e10 Thanks @alicanerdurmaz! - fix: The label and route fields in useMenu().menuItems were marked as deprecated, but they are not actually deprecated. This issue was caused by menuItems extending from IResourceItem, however, menuItems populates these fields and handles deprecation of these fields internally. This change removes the deprecation warning for these fields.

    export const Sider = () => {
      const { menuItems } = useMenu();
      menuItems.map((item) => {
        // these are safe to use
        console.log(item.label);
        console.log(item.route);
        item.children.map((child) => {
          // these are safe to use
          console.log(child.label);
          console.log(child.route);
        });
      });
    
      return <div>{/* ... */}</div>;
    };

    Fixes #6352

  • #6386 bfe28f0316b3623aaef0b60ae39ebe24939dd0af Thanks @hugorezende! - fix(core): wrap setFilters and setSorters methods with useCallback to prevent looping re-renders

    With this we can use the setFilters as dependencies inside useEffects without infinite loop since state changes in the hook won't cause the functions to be re-assigned

    Fixes #6385

4.54.1

Patch Changes

4.54.0

Minor Changes

  • #6180 292cebc5a70f19400793292b79d1400fec114591 Thanks @alicanerdurmaz! - feat: useSelect's queryResult and defaultValueQueryResult is deprecated, use query and defaultValueQuery instead. #6179

    import { useSelect } from '@refinedev/core';
    
    - const { queryResult, defaultValueQueryResult } = useSelect();
    + const { query, defaultValueQuery } = useSelect();

    ✨ You can use @refinedev/codemod to automatically migrate your codebase. Simply run the following command in your project's root directory:

    npx @refinedev/codemod@latest rename-query-and-mutation-result
  • #6116 7e71f12b81954fd3a59678d7fcccd7b557879a94 Thanks @alicanerdurmaz! - feat: Mutation parameters should be given as a prop to the useUpdate hook. #6102 From now on, you can pass mutation parameters to the useUpdate hook as a prop.

    Old usage of useUpdate hook:

    import { useUpdate } from "@refinedev/core";
    
    const { mutate } = useUpdate();
    
    mutate(
      {
        resource: "products",
        id: 1,
        mutationMode: "optimistic",
        successNotification: false,
        values: {
          name: "New Product",
          material: "Wood",
        },
      },
      {
        onSuccess: () => {
          /* do something after mutation success */
        },
      },
    );

    New usage of useUpdate hook:

    import { useUpdate } from "@refinedev/core";
    
    const { mutate } = useUpdate({
      resource: "products",
      successNotification: false,
      mutationMode: "optimistic",
      mutationOptions: {
        onSuccess: () => {
          /* do something after mutation success */
        },
      },
    });
    
    mutate({
      // also you can override the parameters given to the hook
      id: 1,
      values: {
        name: "New Product",
        material: "Wood",
      },
    });

    You can think of the parameters given to the useUpdate hook as default values, while the parameters given to the mutate function are the values used for that specific mutation or dynamic values.

    🚨 If you pass these parameters to the mutate function, it will override the values given to the hook.

  • #6116 7e71f12b81954fd3a59678d7fcccd7b557879a94 Thanks @alicanerdurmaz! - feat: Mutation parameters should be given as a prop to the useCreate hook. #6113 From now on, you can pass mutation parameters to the useCreate hook as a prop.

    Old usage of useCreate hook:

    import { useCreate } from "@refinedev/core";
    
    const { mutate } = useCreate();
    
    mutate(
      {
        resource: "products",
        values: {
          name: "New Product",
          material: "Wood",
        },
        mutationMode: "optimistic",
        successNotification: false,
      },
      {
        onSuccess: () => {
          /* do something after mutation success */
        },
      },
    );

    New usage of useCreate hook:

    import { useCreate } from "@refinedev/core";
    
    const { mutate } = useCreate({
      resource: "products",
      successNotification: false,
      mutationMode: "optimistic",
      mutationOptions: {
        onSuccess: () => {
          /* do something after mutation success */
        },
      },
    });
    
    mutate({
      // also you can override the parameters given to the hook
      values: {
        name: "New Product",
        material: "Wood",
      },
    });

    You can think of the parameters given to the useCreate hook as default values, while the parameters given to the mutate function are the values used for that specific mutation or dynamic values.

    🚨 If you pass these parameters to the mutate function, it will override the values given to the hook.

  • #6172 4967a51944c139d102fcfc04ada5a42c725ed7c2 Thanks @alicanerdurmaz! - feat: useTable's tableQueryResult is deprecated, use tableQuery instead. #6169

    import { useTable } from '@refinedev/core';
    
    - const { tableQueryResult } = useTable();
    + const { tableQuery } = useTable();

    ✨ You can use @refinedev/codemod to automatically migrate your codebase. Simply run the following command in your project's root directory:

    npx @refinedev/codemod@latest rename-query-and-mutation-result
  • #6164 8ed027eec66c41c444f168f4f52e6b51057bc498 Thanks @alicanerdurmaz! - feat: useForm's queryResult is deprecated, use query instead. #6163

    import { useForm } from '@refinedev/core';
    
    - const { queryResult } = useForm();
    + const { query } = useForm();

    ✨ You can use @refinedev/codemod to automatically migrate your codebase. Simply run the following command in your project's root directory:

    npx @refinedev/codemod@latest rename-query-and-mutation-result
  • #6116 7e71f12b81954fd3a59678d7fcccd7b557879a94 Thanks @alicanerdurmaz! - feat: Mutation parameters should be given as a prop to the useCreateMany hook. #6114 From now on, you can pass mutation parameters to the useCreateMany hook as a prop.

    Old usage of useCreateMany hook:

    import { useCreateMany } from "@refinedev/core";
    
    const { mutate } = useCreateMany();
    
    mutate(
      {
        resource: "products",
        values: [
          {
            name: "Product 1",
            material: "Wood",
          },
          {
            name: "Product 2",
            material: "Metal",
          },
        ],
        mutationMode: "optimistic",
        successNotification: false,
      },
      {
        onSuccess: () => {
          /* do something after mutation success */
        },
      },
    );

    New usage of useCreateMany hook:

    import { useCreateMany } from "@refinedev/core";
    
    const { mutate } = useCreateMany({
      resource: "products",
      successNotification: false,
      mutationMode: "optimistic",
      mutationOptions: {
        onSuccess: () => {
          /* do something after mutation success */
        },
      },
    });
    
    mutate({
      // also you can override the parameters given to the hook
      values: [
        {
          name: "Product 1",
          material: "Wood",
        },
        {
          name: "Product 2",
          material: "Metal",
        },
      ],
    });

    You can think of the parameters given to the useCreateMany hook as default values, while the parameters given to the mutate function are the values used for that specific mutation or dynamic values.

    🚨 If you pass these parameters to the mutate function, it will override the values given to the hook.

  • #6174 2b73e40b0e18932f008842790065cdd386e9d270 Thanks @alicanerdurmaz! - feat: useShow's queryResult is deprecated, use query instead. #6173

    import { useShow } from '@refinedev/core';
    
    - const { queryResult } = useShow();
    + const { query } = useShow();

    ✨ You can use @refinedev/codemod to automatically migrate your codebase. Simply run the following command in your project's root directory:

    npx @refinedev/codemod@latest rename-query-and-mutation-result
  • #6164 8ed027eec66c41c444f168f4f52e6b51057bc498 Thanks @alicanerdurmaz! - feat: useForm's mutationResult is deprecated, use mutation instead. #6163

    import { useForm } from '@refinedev/core';
    
    - const { mutationResult } = useForm();
    + const { mutation } = useForm();

    ✨ You can use @refinedev/codemod to automatically migrate your codebase. Simply run the following command in your project's root directory:

    npx @refinedev/codemod@latest rename-query-and-mutation-result
  • #6125 61aa3464df0d95c30839726f455ed43e6854730b Thanks @Dominic-Preap! - fix: update debounce behavior on onSearch in useSelect

    Now debounce behavior is working correctly on onSearch in useSelect when using inside Controller of react-hook-form.

    Resolves #6096

  • #6116 7e71f12b81954fd3a59678d7fcccd7b557879a94 Thanks @alicanerdurmaz! - feat: Mutation parameters should be given as a prop to the useUpdateMany hook. #6115 From now on, you can pass mutation parameters to the useUpdateMany hook as a prop.

    Old usage of useUpdateMany hook:

    import { useUpdateMany } from "@refinedev/core";
    
    const { mutate } = useUpdateMany();
    
    mutate(
      {
        resource: "products",
        values: {
          name: "New Product",
          material: "Wood",
        },
        ids: [1, 2, 3],
        mutationMode: "optimistic",
        successNotification: false,
      },
      {
        onSuccess: () => {
          /* do something after mutation success */
        },
      },
    );

    New usage of useUpdateMany hook:

    import { useUpdateMany } from "@refinedev/core";
    
    const { mutate } = useUpdateMany({
      resource: "products",
      successNotification: false,
      mutationMode: "optimistic",
      mutationOptions: {
        onSuccess: () => {
          /* do something after mutation success */
        },
      },
    });
    
    mutate({
      ids: [1, 2, 3],
      values: {
        name: "New Product",
        material: "Wood",
      },
      // also you can override the parameters given to the hook
    });

    You can think of the parameters given to the useUpdateMany hook as default values, while the parameters given to the mutate function are the values used for that specific mutation or dynamic values.

    🚨 If you pass these parameters to the mutate function, it will override the values given to the hook.

Patch Changes

4.53.0

Minor Changes

Patch Changes

4.51.0

Minor Changes

  • 6bd14228760d3e1e205ea9248e427f9afa2ec046 Thanks @BatuhanW! - Added ina and nina CrudOperators. Added filtering by these operators to Supabase data provider

    5902

  • 6bd14228760d3e1e205ea9248e427f9afa2ec046 Thanks @BatuhanW! - feat(core): ability to pass global app title and icon

    Added ability to pass global app name and icon values through <Refine /> component's options prop.

    Now <Refine /> component accepts options.title prop that can be used to set app icon and app name globally. By default these values will be accessible through useRefineOptions hook and will be used in <ThemedLayoutV2 /> and <AuthPage /> components of the UI packages.

    import { Refine } from "@refinedev/core";
    
    const MyIcon = () => <svg>{/* ... */}</svg>;
    
    const App = () => {
      return (
        <Refine
          options={{
            title: {
              icon: <MyIcon />,
              text: "Refine App",
            },
          }}
        >
          {/* ... */}
        </Refine>
      );
    };

Patch Changes

4.50.0

Minor Changes

  • #5945 a39f1952554120893ea83db904037917fc293dc6 Thanks @aliemir! - Added ina and nina CrudOperators. Added filtering by these operators to Supabase data provider

    5902

  • #5945 903ea231538b00ce02ddc9394c72848ec1e90772 Thanks @aliemir! - feat(core): ability to pass global app title and icon

    Added ability to pass global app name and icon values through <Refine /> component's options prop.

    Now <Refine /> component accepts options.title prop that can be used to set app icon and app name globally. By default these values will be accessible through useRefineOptions hook and will be used in <ThemedLayoutV2 /> and <AuthPage /> components of the UI packages.

    import { Refine } from "@refinedev/core";
    
    const MyIcon = () => <svg>{/* ... */}</svg>;
    
    const App = () => {
      return (
        <Refine
          options={{
            title: {
              icon: <MyIcon />,
              text: "Refine App",
            },
          }}
        >
          {/* ... */}
        </Refine>
      );
    };

Patch Changes

4.49.2

Patch Changes

  • #5928 db9756e7908 Thanks @aliemir! - fix: type errors on typescript <5

    Due to the changes in #5881, typescript users below version 5 are facing type errors. This PR fixes the type errors by updating the file extensions required by the d.mts declaration files to provide a compatible declarations for both typescript 4 and 5 users.

  • Updated dependencies [db9756e7908]:

4.49.1

Patch Changes

  • #5875 1c9a95f22ab Thanks @aliemir! - refactor: add resource name to devtools xray calls

    Added the resource name to the devtools xray calls to allow resource names to be displayed in the devtools even with custom query keys.

  • #5883 0a76576da0f Thanks @aliemir! - fix: development errors being logged when useOnError is called without an auth provider

    When there's no authProvider set, the useOnError hook will log "no mutationFn found" to the console in development because of missing onError property. This PR fixes the issue by providing a dummy onError function when authProvider is not set.

  • #5851 8d2dd4376f6 Thanks @aliemir! - refactor: prevented early accessing signal from useQuery of @tanstack/react-query

    In query hooks, signal was accessed directly by destructuring which was causing issues in development mode with duplicated requests. This change accesses queryContext instead of destructured signal properly to prevent @tanstack/react-query from setting abortSignalConsumed flag unexpectedly.

    Resolves #5843

  • #5875 1c9a95f22ab Thanks @aliemir! - fix: exclude internal button hook calls from devtools trace

    Removed internal button hook calls from devtools trace to avoid crowding the trace with unnecessary information.

  • #5881 ba719f6ea26 Thanks @aliemir! - fix: declaration files in node10, node16 and nodenext module resolutions

  • #5884 9a0c1c8414a Thanks @aliemir! - fix(core): useMenu hideOnMissingParameter prop default value set to true

    There was an error in the useMenu hook's hideOnMissingParameter prop. Its default value should be true but it was missed when props are passed partially. This PR fixes the issue by setting the default value to true.

  • Updated dependencies [1c9a95f22ab, 1c9a95f22ab, ba719f6ea26]:

4.49.0

Minor Changes

  • #5751 f32512b9042 Thanks @aliemir! - Added useResourceParams hook. This hook initially works similarly to useResource but it correctly handles the id and action params per active route and explicit parameters. In @refinedev/core and other Refine packages there was a common logic of handling the id since its inference is dependent on the active resource and route. The same also applies to the action parameter of forms. This hook handles these cases and provides a more consistent API to share the same logic without duplicating it.

    • id and action values returned from useResource is deprecated in favor of useResourceParams.
    • useForm hook is updated to use useResourceParams under the hood.
    • useShow hook is updated to use useResourceParams under the hood.
    • <CanAccess /> component is updated to use useResourceParams under the hood.

Patch Changes

  • #5737 4e8188a6652 Thanks @aliemir! - chore: updated content of README.md to include installation, usage and scaffolding instructions.

  • #5808 10ba9c34490 Thanks @aliemir! - chore: improved useMutationMode hooks usage by accepting explicit values to be passed for mutationMode and undoableTimeout, handling the precedence of the values inside the hook rather than outside to avoid repetition

  • #5733 2b5ac6f5409 Thanks @alicanerdurmaz! - feat: added useTranslation hook. It combines useTranslate, useSetLocale and useGetLocale hooks and returns translate, changeLocale and getLocale methods from that hooks for better developer experience.

    It returns all i18nProvider methods in one hook. It can be used to translate texts, change the locale, and get the current locale in your own components.

    import { useTranslation } from "@refinedev/core";
    
    export const MyComponent = () => {
      const { translate, getLocale, changeLocale } = useTranslation();
      const currentLocale = getLocale();
    
      return (
        <div>
          <h1>{translate("languages")}</h1>
          <button
            onClick={() => changeLocale("en")}
            disabled={currentLocale === "en"}
          >
            English
          </button>
          <button
            onClick={() => changeLocale("de")}
            disabled={currentLocale === "de"}
          >
            German
          </button>
        </div>
      );
    };

    Example of combining useTranslation with useTranslate, useSetLocale and useGetLocale hooks.

    import {
    -  useGetLocale,
    -  useSetLocale,
    -  useTranslate,
    +  useTranslation,
    } from "@refinedev/core";
    
    export const MyComponent = () => {
    -  const changeLocale = useSetLocale();
    -  const getLocale = useGetLocale();
    -  const translate = useTranslate();
    
    +  const { translate, getLocale, changeLocale } = useTranslation();
    
      return <div>{/* ... */}</div>;
    };
  • #5765 0c197d82393 Thanks @aliemir! - refactor: package bundles and package.json configuration for exports

    Previously, Refine packages had exported ESM and CJS bundles with same .js extension and same types for both with .d.ts extensions. This was causing issues with bundlers and compilers to pick up the wrong files for the wrong environment. Now we're outputting ESM bundles with .mjs extension and CJS bundles with .cjs extension. Also types are now exported with both .d.mts and .d.cts extensions.

    In older versions ESM and CJS outputs of some packages were using wrong imports/requires to dependencies causing errors in some environments. This will be fixed since now we're also enforcing the module type with extensions.

    Above mentioned changes also supported with changes in package.json files of the packages to support the new extensions and types. All Refine packages now include exports fields in their configuration to make sure the correct bundle is picked up by the bundlers and compilers.

  • #5765 0c197d82393 Thanks @aliemir! - Fixed the lodash-es imports for ESM builds to access the exports properly.

  • #5755 404b2ef5e1b Thanks @BatuhanW! - feat: refactor TS typings.

    Type definitions in src/interfaces folder moved to their main consumer's folder under types.ts files.

  • #5754 56ed144a0f5 Thanks @alicanerdurmaz! - chore: TypeScript upgraded to v5.x.x. #5752

  • #5765 0c197d82393 Thanks @aliemir! - Update papaparse imports to fix ESM exports to work properly

  • #5808 10ba9c34490 Thanks @aliemir! - feat: added headless button hooks

    We've added a new set of hooks to make it easier to create and manage UI buttons of Refine. There's a hook for each type of button which previously had duplicated logic across the codebase between UI integrations of Refine. Now all these buttons will be powered by the same hooks maintained in the @refinedev/core package to ensure consistency and reduce duplication.

    New Hooks:

    • useListButton: A navigation button that navigates to the list page of a resource.
    • useCreateButton: A navigation button that navigates to the create page of a resource.
    • useShowButton: A navigation button that navigates to the show page of a record.
    • useEditButton: A navigation button that navigates to the edit page of a record.
    • useCloneButton: A navigation button that navigates to the clone page of a record.
    • useRefreshButton: A button that triggers an invalidation of the cache of a record.
    • useDeleteButton: A button that triggers a delete mutation on a record.
    • useSaveButton: A button to be used inside a form to trigger a save mutation.
    • useExportButton: A button to be used with useExport to trigger an export bulk data of a resource.
    • useImportButton: A button to be used with useImport to trigger an import bulk data for a resource.
  • #5714 38f129f40ee Thanks @aliemir! - Refactored the internal logic of useForm to be more efficient and readable, along with few bug fixes and improvements to the useForm hook.

    These changes are related to the issue #5702 and resolves #5460.

    • onFinish now rejects when; - values is not provided, - resource is not defined, - id is required but not provided. previously these cases were silently ignored.
    • Same changes also applies to onFinishAutoSave.
    • onFinishAutoSave had an issue with returning the appropriate promise after being called. This resulted in unhandled promise rejections and uncontrollable resolved promises. Now it is fixed, onFinishAutoSave will resolve and reject based on the response of the mutation.
    • When using auto save, debounced calls will now be cancelled and the respective promises will be rejected with "cancelled by debounce" message. These changes might require an update to the code bases that uses onFinishAutoSave to handle the rejection of the promise to avoid unhandled promise rejections.
    • Combined the separated submit functions into one for sake of simplicity and consistency. (internal)
    • onFinish rejects and resolved regardless of the onMutationSuccess and onMutationError hooks are provided or not. (Resolves #5460)
    • meta values were concatenated multiple times causing confusion and unexpected behavior, now it is fixed. (internal)
    • Moved the id determination/inference logic to a separate hook. (internal) -
  • Updated dependencies [0c197d82393, 56ed144a0f5]:

4.48.0

Minor Changes

  • #5609 fd38d9c71a6 Thanks @Cavdy! - feat: ability to pass an argument to usePermissions #5607

    Ability to pass an argument or parameters to usePermissions hook

    const params = { tenantId: "id" };
    usePermissions({ params });

    Resolves #5607

  • #5610 17c39ee2ee0 Thanks @Conqxeror! - feat: allow passing function to optionLabel and optionValue props for useSelect hook.

    const { options } = useSelect({
      optionLabel: (item) => `${item.firstName} ${item.lastName}`,
      optionValue: (item) => item.id,
    });

    feat: add searchField prop to useSelect hook.

    Can be used to specify which field will be searched with value given to onSearch function.

    const { onSearch } = useSelect({ searchField: "name" });
    
    onSearch("John"); // Searchs by `name` field with value John.

    By default, it uses optionLabel's value, if optionLabel is a string. Uses title field otherwise.

    // When `optionLabel` is string.
    const { onSearch } = useSelect({ optionLabel: "name" });
    
    onSearch("John"); // Searchs by `name` field with value John.
    
    // When `optionLabel` is function.
    const { onSearch } = useSelect({
      optionLabel: (item) => `${item.id} - ${item.name}`,
    });
    
    onSearch("John"); // Searchs by `title` field with value John.

    Resolves #4880

Patch Changes

4.47.2

Patch Changes

4.47.1

Patch Changes

4.47.0

Minor Changes

  • #5538 b91de14ac8 Thanks @Conqxeror! - feat: ability to configure useCan's queryOptions globally and through CanAccess component. #5472

  • #5522 71148278cb Thanks @Conqxeror! - feat(core): add success notification support for auth provider methods #5473

    Updated the core and added successNotification field to AuthActionResponse and Updated relevant hooks to show success notification when successNotification object is provided and added specs.

Patch Changes

  • #5525 e2355e4179 Thanks @aliemir! - Updated <WelcomePage /> component to use RefineContext to determine if the context is defined or not. It will show an error dialog if the context is not defined. If the error is showing, it means that <Refine /> component is not mounted or <WelcomePage /> component is used outside of <Refine /> component.

  • #5332 5e65f71ecd Thanks @vikavorkin! - fix: replace export-to-csv-fix-source-map with papaparse #5317

    Replace usage of export-to-csv-fix-source-map to papaparse, fixing issues with useExport hook.

  • #5526 b094b50c51 Thanks @aliemir! - Marked dataProvider prop of <Refine /> component as optional. This will allow users to setup Refine gradually without having to provide a data provider.

  • #5503 4b4d34208c Thanks @BatuhanW! - refactor(core): re-export AuthBindings type as AuthProvider for consistency.

4.46.2

Patch Changes

  • #5423 75bb61dd3b Thanks @aliemir! - Updated flattenObjectKeys method to support both nested and non-nested variables when propagating server side errors to form fields. Resolves #5461

  • #5401 93e00fd770 Thanks @alicanerdurmaz! - fix: queryKey is not overrideable. To fix this, useQuery overloads refactored with single argument objects.

    - useQuery(queryKey, queryFn, options);
    + useQuery({ queryKey, queryFn, ...options });

    From now on, you can pass queryKey as an object property.

    // all data hooks can be used with this syntax.
    useList({
      queryOptions: {
        queryKey: ["my-query-key"],
      },
    });
  • #5406 e5888b6b9c Thanks @aliemir! - useMenu hook was using outdated meta and router params due to missing dependency of the callback function. This was causing dynamic menu items to use wrong paths as links. (Resolves #5432)

  • #5452 b621223bfb Thanks @aliemir! - Added the ability to pass meta properties when using useGo's go function with to as a resource object. This allows you to pass additional path parameters to the path defined in the resources array within the <Refine /> component. Resolves #5451

    Assume we have the following resource defined in the <Refine /> component:

    {
        name: "posts",
        list: "/posts",
        edit: "/:foo/posts/:id/edit",
    }
    import { useGo } from "@refinedev/core";
    
    const MyButton = () => {
      const go = useGo();
    
      return (
        <Button
          onClick={() => {
            go({
              to: {
                resource: "posts",
                action: "edit",
                id: "1",
                meta: {
                  foo: "bar",
                },
              },
              type: "push",
            });
            // generated path will be "/bar/posts/1/edit"
          }}
        >
          Go Posts
        </Button>
      );
    };
  • #5381 19ceffbe9f Thanks @aberhamm! - fix: Missing loginLink attribute in AuthPageProps for <AuthPage type="register" />. #5381

4.46.1

Patch Changes

  • #5409 0026fe34d0 Thanks @BatuhanW! - fix: exclude gqlMutation and gqlQuery from building query keys for useUpdate, useUpdateMany, useDelete, and useDeleteMany hooks.

  • #5409 0026fe34d0 Thanks @BatuhanW! - feat: add optional gqlQuery and gqlMutation fields to MetaQuery type to be used in data hooks.

    We plan to utilize these fields on our GraphQL data providers in the future.

    You can build your queries/mutations with graphql-tag package and pass it to the gqlQuery/gqlMutation fields.

    For now, only @refinedev/nestjs-query package supports it.

    import { useList } from "@refinedev/core";
    import gql from "graphql-tag";
    
    const PRODUCTS_QUERY = gql`
      query ProductsList(
        $paging: OffsetPaging!
        $filter: BlogPostFilter
        $sorting: [BlogPostSort!]!
      ) {
        products(paging: $paging, filter: $filter, sorting: $sorting) {
          nodes {
            id
            name
          }
          totalCount
        }
      }
    `;
    
    const { data } = useList({
      resource: "products",
      meta: { gqlQuery: PRODUCTS_QUERY },
    });

4.46.0

Minor Changes

  • #5343 dd8f1270f6 Thanks @alicanerdurmaz! - fix: hideForm should remove all form fields. (submit button, form fields, rememberMe checkbox, forgot password link, etc.) but the /register link should be visible.

  • #5307 f8e407f850 Thanks @jackprogramsjp! - feat: added hideForm props for LoginPage and RegisterPage for AuthPage feature.

    Now with the hideForm props feature, you can be able to hide the forms (like email/password) to only show the OAuth providers. This avoids having to make your own entire AuthPage.

Patch Changes

  • #5323 17aa8c1cd6 Thanks @alicanerdurmaz! - ### Breaking changes

    fix: added required key prop to <Authenticated /> component to resolve issues of rendering of the unwanted content and wrongful redirections. #4782

    Why is it required?

    Due to the nature of React, components are not unmounted and remounted again if props are changed. While this is mostly a good practice for performance, in some cases you'll want your component to re-mount instead of updating; for example, if you don't want to use any of the previous states and effects initiated with the old props.

    The <Authenticated /> component has this kind of scenario when it's used for page-level authentication checks. If the previous check results were used for the rendering of the content (fallback or children) this may lead to unexpected behaviors and flashing of the unwanted content.

    To avoid this, a key property must be set with different values for each use of the <Authenticated /> components. This will make sure that React will unmount and remount the component instead of updating the props.

    import { Refine, Authenticated, AuthPage } from "@refinedev/core";
    import {
      CatchAllNavigate,
    } from "@refinedev/react-router";
    import { BrowserRouter, Routes, Route, Outlet, Navigate } from "react-router";
    
    const App = () => {
      return (
        <BrowserRouter>
          <Refine {/* ... */}>
            <Routes>
              <Route
                element={
                  <Authenticated
                    key="authenticated-routes"
                    fallback={<CatchAllNavigate to="/login" />}
                  >
                    <Outlet />
                  </Authenticated>
                }
              >
                <Route index element={<h1>Dashboard Page</h1>} />
              </Route>
    
              <Route
                element={
                  <Authenticated key="unauthenticated-routes" fallback={<Outlet />}>
                     <Navigate to="/" replace />
                  </Authenticated>
                }
              >
                <Route path="/login" element={<AuthPage type="login" />} />
              </Route>
            </Routes>
          </Refine>
        </BrowserRouter>
      );
    };

    In the example above, the <Authenticated /> is rendered as the wrapper of both the index route and /login route. Without a key property, <Authenticated /> will not be re-mounted and can result in rendering the content depending on the previous authentication check. This will lead to redirecting to /login when trying to access the index route instead of rendering the content of the index or navigating to index route instead of /login if the user just logged out.

  • #5339 4c49ef0a06 Thanks @alicanerdurmaz! - feat: <WelcomePage /> component redesigned.

  • #5316 3bdb9cb1cb Thanks @ksankeerth! - fix: Return type is not mentioned correctly in useOne, useSelect, useForm, useMany and useShow hooks

    This fix has improved type safety of return type of useOne, useSelect, useForm, useMany and useShow hooks.

4.45.1

Patch Changes

4.45.0

Minor Changes

  • #5259 eac3df87ffb Thanks @aliemir! - Added <AutoSaveIndicator /> component and updated the AutoSaveIndicatorProps type to allow elements to be passed in.

    elements prop is an object with success, error, loading and idle keys. Each key is a React element that will be rendered when the corresponding state is active.

    By default every state will render a span with the translated text of the autoSave.${state} key.

Patch Changes

4.44.12

Patch Changes

4.44.11

Patch Changes

  • #5199 2b8d658a17a Thanks @aliemir! - Exported BaseOption type as successor of the deprecated Option type. BaseOption is { label: any; value: any; }.

    Usage of the deprecated Option type was correctly assuming that the value property of the option is of type string. This assumption was wrong and now the types are changed to reflect the correct values of options with the ability to change it via 4th generic type TOption of useSelect hook.

  • #5199 2b8d658a17a Thanks @aliemir! - Reverted the faulty assumption on option values of useSelect hook to be of type string. Now changed the types and the logic to reflect the correct values of options with the ability to change it via 4th generic type TOption of useSelect hook. (Reverted PR #5160)

    By default TOption will be equal to BaseOption type which is { label: any; value: any; }. If you want to change the type of options, you can do it like this:

    import { HttpError, useSelect } from "@refinedev/core";
    
    type MyData = {
      id: number;
      title: string;
      description: string;
      category: { id: string };
    };
    
    type Option = { label: MyData["title"]; value: MyData["id"] }; // equals to { label: string; value: number; }
    
    useSelect<MyData, HttpError, MyData, Option>({
      resource: "posts",
    });
  • #5194 9df999ca643 Thanks @fitrahfm! - fix: use relative path instead of path alias to import FlatTreeItem

    Using path alias causes imported types being any during build/compilation process which should be TreeMenuItem[]

  • #5201 760cfbaaa2a Thanks @aliemir! - Exported the flattenObjectKeys and propertyPathToArray helpers from @refinedev/core package.

4.44.10

Patch Changes

  • #5199 2b8d658a17a Thanks @aliemir! - Exported BaseOption type as successor of the deprecated Option type. BaseOption is { label: any; value: any; }.

    Usage of the deprecated Option type was correctly assuming that the value property of the option is of type string. This assumption was wrong and now the types are changed to reflect the correct values of options with the ability to change it via 4th generic type TOption of useSelect hook.

  • #5199 2b8d658a17a Thanks @aliemir! - Reverted the faulty assumption on option values of useSelect hook to be of type string. Now changed the types and the logic to reflect the correct values of options with the ability to change it via 4th generic type TOption of useSelect hook. (Reverted PR #5160)

    By default TOption will be equal to BaseOption type which is { label: any; value: any; }. If you want to change the type of options, you can do it like this:

    import { HttpError, useSelect } from "@refinedev/core";
    
    type MyData = {
      id: number;
      title: string;
      description: string;
      category: { id: string };
    };
    
    type Option = { label: MyData["title"]; value: MyData["id"] }; // equals to { label: string; value: number; }
    
    useSelect<MyData, HttpError, MyData, Option>({
      resource: "posts",
    });
  • #5194 9df999ca643 Thanks @fitrahfm! - fix: use relative path instead of path alias to import FlatTreeItem

    Using path alias causes imported types being any during build/compilation process which should be TreeMenuItem[]

  • #5201 760cfbaaa2a Thanks @aliemir! - Exported the flattenObjectKeys and propertyPathToArray helpers from @refinedev/core package.

4.44.9

Patch Changes

4.44.8

Patch Changes

4.44.7

Patch Changes

  • #5138 0e22d5804b2 Thanks @aliemir! - Prevent authProvider.getIdentity to be called in useLog if auditLogProvider is not defined.

4.44.6

Patch Changes

  • #5138 0e22d5804b2 Thanks @aliemir! - Prevent authProvider.getIdentity to be called in useLog if auditLogProvider is not defined.

4.44.5

Patch Changes

  • #5087 88d52d639b9 Thanks @alicanerdurmaz! - feat: meta props added liveProvider.subscribe and liveProvider.publish methods. From now on, you can use meta to distinguish between methods by meta.

    meta type:

    import { QueryFunctionContext } from "@tanstack/react-query";
    
    type Fields = Array<string | object | NestedField>;
    
    type VariableOptions =
      | {
          type?: string;
          name?: string;
          value: any;
          list?: boolean;
          required?: boolean;
        }
      | { [k: string]: any };
    
    type Meta = {
      dataProviderName?: string;
      operation?: string;
      fields?: Fields;
      variables?: VariableOptions;
      queryContext?: QueryFunctionContext;
      [k: string]: any;
    };

    Usage

    import { LiveProvider, LiveEvent } from "@refinedev/core";
    
    export const liveProvider = (client: any): LiveProvider => {
      return {
        subscribe: ({ channel, types, params, callback, meta }) => {
          console.log({ meta });
        },
    
        publish: ({ channel, type, payload, date, meta }: LiveEvent) => {
          console.log({ meta });
        },
      };
    };

4.44.4

Patch Changes

  • #5087 88d52d639b9 Thanks @alicanerdurmaz! - feat: meta props added liveProvider.subscribe and liveProvider.publish methods. From now on, you can use meta to distinguish between methods by meta.

    meta type:

    import { QueryFunctionContext } from "@tanstack/react-query";
    
    type Fields = Array<string | object | NestedField>;
    
    type VariableOptions =
      | {
          type?: string;
          name?: string;
          value: any;
          list?: boolean;
          required?: boolean;
        }
      | { [k: string]: any };
    
    type Meta = {
      dataProviderName?: string;
      operation?: string;
      fields?: Fields;
      variables?: VariableOptions;
      queryContext?: QueryFunctionContext;
      [k: string]: any;
    };

    Usage

    import { LiveProvider, LiveEvent } from "@refinedev/core";
    
    export const liveProvider = (client: any): LiveProvider => {
      return {
        subscribe: ({ channel, types, params, callback, meta }) => {
          console.log({ meta });
        },
    
        publish: ({ channel, type, payload, date, meta }: LiveEvent) => {
          console.log({ meta });
        },
      };
    };

4.44.3

Patch Changes

  • #5050 613af0021f6 Thanks @alicanerdurmaz! - feat: pass dataProviderName to liveProvider.subscribe method. From now on, you can use dataProviderName to distinguish between different data providers in live provider.

    Refer to documentation for more info about multiple data providers ->

    Usage

    import { useForm, useList } from "@refinedev/core";
    
    useList({
      dataProviderName: "first-data-provider",
    });
    
    useForm({
      dataProviderName: "second-data-provider",
    });
    import { LiveProvider } from "@refinedev/core";
    
    export const liveProvider = (client: any): LiveProvider => {
      return {
        subscribe: ({ channel, types, params, callback, dataProviderName }) => {
          console.log({ dataProviderName }); //  "second-data-provider"
        },
      };
    };
  • #5053 857d4020a30 Thanks @alicanerdurmaz! - feat: The parameter types of data provider methods have been exported. From now on, you can use the parameter types of Data Provider methods.

    import type {
        DataProvider,
        GetListResponse
        // new exported types
        GetListParams,
        GetManyParams,
        GetOneParams,
        CreateParams,
        CreateManyParams,
        UpdateParams,
        UpdateManyParams,
        DeleteOneParams,
        DeleteManyParams,
        CustomParams,
    } from "@refinedev/core";
    
    const myDataProvider: DataProvider = {
        getList: async (params: GetListParams): Promise<GetListResponse<any>> => {
            return { data: [], total: 0 };
        },
    };

4.44.2

Patch Changes

  • #5050 613af0021f6 Thanks @alicanerdurmaz! - feat: pass dataProviderName to liveProvider.subscribe method. From now on, you can use dataProviderName to distinguish between different data providers in live provider.

    Refer to documentation for more info about multiple data providers ->

    Usage

    import { useForm, useList } from "@refinedev/core";
    
    useList({
      dataProviderName: "first-data-provider",
    });
    
    useForm({
      dataProviderName: "second-data-provider",
    });
    import { LiveProvider } from "@refinedev/core";
    
    export const liveProvider = (client: any): LiveProvider => {
      return {
        subscribe: ({ channel, types, params, callback, dataProviderName }) => {
          console.log({ dataProviderName }); //  "second-data-provider"
        },
      };
    };
  • #5053 857d4020a30 Thanks @alicanerdurmaz! - feat: The parameter types of data provider methods have been exported. From now on, you can use the parameter types of Data Provider methods.

    import type {
        DataProvider,
        GetListResponse
        // new exported types
        GetListParams,
        GetManyParams,
        GetOneParams,
        CreateParams,
        CreateManyParams,
        UpdateParams,
        UpdateManyParams,
        DeleteOneParams,
        DeleteManyParams,
        CustomParams,
    } from "@refinedev/core";
    
    const myDataProvider: DataProvider = {
        getList: async (params: GetListParams): Promise<GetListResponse<any>> => {
            return { data: [], total: 0 };
        },
    };

4.44.1

Patch Changes

  • #5050 613af0021f6 Thanks @alicanerdurmaz! - feat: pass dataProviderName to liveProvider.subscribe method. From now on, you can use dataProviderName to distinguish between different data providers in live provider.

    Refer to documentation for more info about multiple data providers ->

    Usage

    import { useForm, useList } from "@refinedev/core";
    
    useList({
      dataProviderName: "first-data-provider",
    });
    
    useForm({
      dataProviderName: "second-data-provider",
    });
    import { LiveProvider } from "@refinedev/core";
    
    export const liveProvider = (client: any): LiveProvider => {
      return {
        subscribe: ({ channel, types, params, callback, dataProviderName }) => {
          console.log({ dataProviderName }); //  "second-data-provider"
        },
      };
    };
  • #5053 857d4020a30 Thanks @alicanerdurmaz! - feat: The parameter types of data provider methods have been exported. From now on, you can use the parameter types of Data Provider methods.

    import type {
        DataProvider,
        GetListResponse
        // new exported types
        GetListParams,
        GetManyParams,
        GetOneParams,
        CreateParams,
        CreateManyParams,
        UpdateParams,
        UpdateManyParams,
        DeleteOneParams,
        DeleteManyParams,
        CustomParams,
    } from "@refinedev/core";
    
    const myDataProvider: DataProvider = {
        getList: async (params: GetListParams): Promise<GetListResponse<any>> => {
            return { data: [], total: 0 };
        },
    };

4.44.0

Minor Changes

  • #5034 85bcff15d1e Thanks @alicanerdurmaz! - feat: The go function returned by useGo now accepts a resource object as the to parameter. From now now, you can provide either a string or a resource object to the go function. When a resource object is passed, it will be transformed into the path defined within the resources array of the <Refine /> component.

    to accepts an object with the following shape to navigate to a resource:

    | Name | Type | Description | | -------- | ----------------------------------------------------------- | ----------------------------------------------------------- | | resource | string | resource name or identifier. | | id | [BaseKey][basekey] | required when action is "edit", "show", or "clone". | | action | "list" | "create" | "edit" | "show" | "clone" | action name. |

    import { useGo } from "@refinedev/core";
    
    const MyComponent = () => {
        const go = useGo();
    
        return (
            <Button
                onClick={() => {
                    go({
                        to:  {
                            resource: "posts", // resource name or identifier
                            action: "edit",
                            id: "1",
                        }
                        query: {
                             foo: "bar",
                        },
                        type: "push",
                    });
                }}
            >
                Go Posts With Default Filters
            </Button>
        );
    };

4.43.0

Minor Changes

  • #5034 85bcff15d1e Thanks @alicanerdurmaz! - feat: The go function returned by useGo now accepts a resource object as the to parameter. From now now, you can provide either a string or a resource object to the go function. When a resource object is passed, it will be transformed into the path defined within the resources array of the <Refine /> component.

    to accepts an object with the following shape to navigate to a resource:

    | Name | Type | Description | | -------- | ----------------------------------------------------------- | ----------------------------------------------------------- | | resource | string | resource name or identifier. | | id | [BaseKey][basekey] | required when action is "edit", "show", or "clone". | | action | "list" | "create" | "edit" | "show" | "clone" | action name. |

    import { useGo } from "@refinedev/core";
    
    const MyComponent = () => {
        const go = useGo();
    
        return (
            <Button
                onClick={() => {
                    go({
                        to:  {
                            resource: "posts", // resource name or identifier
                            action: "edit",
                            id: "1",
                        }
                        query: {
                             foo: "bar",
                        },
                        type: "push",
                    });
                }}
            >
                Go Posts With Default Filters
            </Button>
        );
    };

4.42.4

Patch Changes

4.42.3

Patch Changes

4.42.2

Patch Changes

4.42.1

Patch Changes

4.42.0

Minor Changes

  • #4960 d8e464fa2c4 Thanks @aliemir! - Added devtools internals and integrated with the core hooks. Now users will be able to track the queries and mutation made by refine through refine devtools.

Patch Changes

4.41.0

Minor Changes

  • #4960 d8e464fa2c4 Thanks @aliemir! - Added devtools internals and integrated with the core hooks. Now users will be able to track the queries and mutation made by refine through refine devtools.

Patch Changes

4.40.0

Minor Changes

  • #4914 91a4d0da9f1 Thanks @yildirayunlu! - feat: add optimisticUpdateMap prop to the useUpdate and useUpdateMany hooks

    list, many and detail are the keys of the optimisticUpdateMap object. To automatically update the cache, you should pass true. If you don't want to update the cache, you should pass false.

    If you wish to customize the cache update, you have the option to provide functions for the list, many, and detail keys. These functions will be invoked with the previous data, values, and id parameters. Your responsibility is to return the updated data within these functions.

    const { mutate } = useUpdateMany();
    
    mutate({
      //...
      mutationMode: "optimistic",
      optimisticUpdateMap: {
        list: true,
        many: true,
        detail: (previous, values, id) => {
          if (!previous) {
            return null;
          }
    
          const data = {
            id,
            ...previous.data,
            ...values,
            foo: "bar",
          };
    
          return {
            ...previous,
            data,
          };
        },
      },
    });

    feat: add optimisticUpdateMap prop to the useForm hook

    const { formProps, saveButtonProps } = useForm({
      mutationMode: "optimistic",
      optimisticUpdateMap: {
        list: true,
        many: true,
        detail: (previous, values, id) => {
          if (!previous) {
            return null;
          }
    
          const data = {
            id,
            ...previous.data,
            ...values,
            foo: "bar",
          };
    
          return {
            ...previous,
            data,
          };
        },
      },
    });

Patch Changes

4.39.0

Minor Changes

  • #4914 91a4d0da9f1 Thanks @yildirayunlu! - feat: add optimisticUpdateMap prop to the useUpdate and useUpdateMany hooks

    list, many and detail are the keys of the optimisticUpdateMap object. To automatically update the cache, you should pass true. If you don't want to update the cache, you should pass false.

    If you wish to customize the cache update, you have the option to provide functions for the list, many, and detail keys. These functions will be invoked with the previous data, values, and id parameters. Your responsibility is to return the updated data within these functions.

    const { mutate } = useUpdateMany();
    
    mutate({
      //...
      mutationMode: "optimistic",
      optimisticUpdateMap: {
        list: true,
        many: true,
        detail: (previous, values, id) => {
          if (!previous) {
            return null;
          }
    
          const data = {
            id,
            ...previous.data,
            ...values,
            foo: "bar",
          };
    
          return {
            ...previous,
            data,
          };
        },
      },
    });

    feat: add optimisticUpdateMap prop to the useForm hook

    const { formProps, saveButtonProps } = useForm({
      mutationMode: "optimistic",
      optimisticUpdateMap: {
        list: true,
        many: true,
        detail: (previous, values, id) => {
          if (!previous) {
            return null;
          }
    
          const data = {
            id,
            ...previous.data,
            ...values,
            foo: "bar",
          };
    
          return {
            ...previous,
            data,
          };
        },
      },
    });

Patch Changes

4.38.4

Patch Changes

  • #4951 04837c62077 Thanks @aliemir! - - Update build configuration for esbuild to use the shared plugins.
    • Fix the lodash replacement plugin to skip redundant files.

4.38.3

Patch Changes

  • #4951 04837c62077 Thanks @aliemir! - - Update build configuration for esbuild to use the shared plugins.
    • Fix the lodash replacement plugin to skip redundant files.

4.38.2

Patch Changes

4.38.1

Patch Changes

4.38.0

Minor Changes

  • #4906 58d3d605510 Thanks @alicanerdurmaz! - feat: added onUnauthorized callback to <CanAccess /> component. This callback to be called when useCan returns false.

    <CanAccess
      onUnauthorized={({ resource, reason, action, params }) =>
        console.log(
          `You cannot access ${resource}-${params.id} resource with ${action} action because ${reason}`,
        )
      }
    >
      <YourComponent />
    </CanAccess>

Patch Changes

4.37.0

Minor Changes

  • #4906 58d3d605510 Thanks @alicanerdurmaz! - feat: added onUnauthorized callback to <CanAccess /> component. This callback to be called when useCan returns false.

    <CanAccess
      onUnauthorized={({ resource, reason, action, params }) =>
        console.log(
          `You cannot access ${resource}-${params.id} resource with ${action} action because ${reason}`,
        )
      }
    >
      <YourComponent />
    </CanAccess>

Patch Changes

4.36.2

Patch Changes

  • #4896 daabcd666be Thanks @aliemir! - useInvalidate now returns a promise that resolves when the invalidation is completed.

  • #4896 daabcd666be Thanks @aliemir! - Fine-tuning the invalidation process by setting up additional filters and options for the invalidation.

    Now after a successful mutation, refine will invalidate all the queries in the scope but trigger a refetch only for the active queries. If there are any ongoing queries, they will be kept as they are.

    After receiving a realtime subscription event, refine will invalidate and refetch only the active queries.

4.36.1

Patch Changes

  • #4896 daabcd666be Thanks @aliemir! - useInvalidate now returns a promise that resolves when the invalidation is completed.

  • #4896 daabcd666be Thanks @aliemir! - Fine-tuning the invalidation process by setting up additional filters and options for the invalidation.

    Now after a successful mutation, refine will invalidate all the queries in the scope but trigger a refetch only for the active queries. If there are any ongoing queries, they will be kept as they are.

    After receiving a realtime subscription event, refine will invalidate and refetch only the active queries.

4.36.0

Minor Changes

  • #4865 946e13408e7 Thanks @aliemir! - Updated query keys to be more consistent and structured.

    Added mutation keys to the useMutation calls with the same structure as the query keys.

    Added options.useNewQueryKeys option to the <Refine> component for opting into the new query keys.

    Check out the documentation for more information.

4.35.0

Minor Changes

  • #4865 946e13408e7 Thanks @aliemir! - Updated query keys to be more consistent and structured.

    Added mutation keys to the useMutation calls with the same structure as the query keys.

    Added options.useNewQueryKeys option to the <Refine> component for opting into the new query keys.

    Check out the documentation for more information.

4.34.0

Minor Changes

  • #4775 3052fb22449 Thanks @alicanerdurmaz! - feat: queryKeys and pickDataProvider functions are exported.

    pickDataProvider: returns the data provider name based on the provided name or fallbacks to resource definition, or default.

    queryKeys: returns the query keys used by the data hooks based on the resource definition

4.33.0

Minor Changes

  • #4775 3052fb22449 Thanks @alicanerdurmaz! - feat: queryKeys and pickDataProvider functions are exported.

    pickDataProvider: returns the data provider name based on the provided name or fallbacks to resource definition, or default.

    queryKeys: returns the query keys used by the data hooks based on the resource definition

4.32.2

Patch Changes

4.32.1

Patch Changes

4.32.0

Minor Changes

  • #4741 026ccf34356 Thanks @aliemir! - Added sideEffects: false to package.json to help bundlers tree-shake unused code.

4.31.0

Minor Changes

  • #4741 026ccf34356 Thanks @aliemir! - Added sideEffects: false to package.json to help bundlers tree-shake unused code.

4.30.0

Minor Changes

  • #4742 61950c8fe18 Thanks @aliemir! - Removed @tanstack/react-query-devtools package and its usage from refine's core. This means that you will no longer see the dev tools icon in the bottom right corner of your app by default. If you want to use the dev tools, you can install the package (@tanstack/react-query-devtools) and use it in your app.

    options.reactQuery.devtoolConfig property has been removed from the <Refine> components props. This option will no longer be functional and will be removed in the next major release. If you have any configuration for the dev tools, you can pass it to the ReactQueryDevtools component directly.

Patch Changes

  • #4740 41018fde9ff Thanks @aliemir! - Use fetch for telemetry calls as a fallback for Image when it's not available. This fixes an issue where telemetry calls would fail in some environments.

4.29.0

Minor Changes

  • #4742 61950c8fe18 Thanks @aliemir! - Removed @tanstack/react-query-devtools package and its usage from refine's core. This means that you will no longer see the dev tools icon in the bottom right corner of your app by default. If you want to use the dev tools, you can install the package (@tanstack/react-query-devtools) and use it in your app.

    options.reactQuery.devtoolConfig property has been removed from the <Refine> components props. This option will no longer be functional and will be removed in the next major release. If you have any configuration for the dev tools, you can pass it to the ReactQueryDevtools component directly.

Patch Changes

  • #4740 41018fde9ff Thanks @aliemir! - Use fetch for telemetry calls as a fallback for Image when it's not available. This fixes an issue where telemetry calls would fail in some environments.

4.28.2

Patch Changes

  • #4696 35a2c695a74 Thanks @BatuhanW! - feat: add optional projectId field to <Refine /> component options prop. Project ID will be sent with telemetry data if it exists.

4.28.1

Patch Changes

  • #4696 35a2c695a74 Thanks @BatuhanW! - feat: add optional projectId field to <Refine /> component options prop. Project ID will be sent with telemetry data if it exists.

4.28.0

Minor Changes

  • #4652 96af6d25b7a Thanks @alicanerdurmaz! - feat: added errros field to HttpError type. From now on, you can pass errors field to HttpError. This field will be used to update the useForm's error state.

    export interface ValidationErrors {
      [field: string]:
        | string
        | string[]
        | boolean
        | { key: string; message: string };
    }
    
    export interface HttpError extends Record<string, any> {
      message: string;
      statusCode: number;
      errors?: ValidationErrors;
    }

    Usage example:

    import { HttpError } from "@refinedev/core";
    
    const App = () => {
      return (
        <Refine
          routerProvider={routerProvider}
          dataProvider={{
            // ...
            update: async () => {
              // assume that the server returns the following error
              const error: HttpError = {
                message: "An error occurred while updating the record.",
                statusCode: 400,
                //This field will be used to update the `useForm`'s error state
                errors: {
                  title: [
                    "Title is required.",
                    "Title should have at least 5 characters.",
                  ],
                  "category.id": ["Category is required."],
                  status: true,
                  content: {
                    key: "form.error.content",
                    message: "Content is required.",
                  },
                },
              };
    
              return Promise.reject(error);
            },
          }}
        >
          {/* ... */}
        </Refine>
      );
    };

    Refer to the server-side form validation documentation for more information. →

  • #4652 96af6d25b7a Thanks @alicanerdurmaz! - feat: added disableServerSideValidation to the refine options for globally disabling server-side validation.

    import { Refine } from "@refinedev/core";
    
    <Refine
      options={{
        disableServerSideValidation: true,
      }}
    >
      // ...
    </Refine>;
  • #4591 f8891ead2bd Thanks @yildirayunlu! - feat: autoSave feature for useForm hook now accept autoSave object. enabled is a boolean value and debounce is a number value in milliseconds. debounce is optional and default value is 1000. autoSaveProps is an object that contains data, error and status values. data is the saved data, error is the error object and status is the status of the request. status can be loading, error, idle and success.

    const { autoSaveProps } = useForm({
        autoSave: {
            enabled: true,
            debounce: 2000, // not required, default is 1000
        },
    });

Patch Changes

  • #4659 3af99896101 Thanks @salihozdemir! - chore: fix tsdoc description of onCancel property on following hooks:

    • useUpdate
    • useUpdateMany
    • useDelete
    • useDeleteMany
  • #4665 3442f4bd00a Thanks @yildirayunlu! - feat: add false return type on SuccessErrorNotification

    This issue has been fixed in this PR, where the successNotification and errorNotification methods can now return false when a callback function is given. This allows the conditional notification to be displayed.

    const { mutate } = useCreate<IPost>({});
    
    mutate({
        resource: "posts",
        values: {
            title: "Hello World",
            status: "published",
        },
        successNotification: (data) => {
            if (data?.data.status === "published") {
                return {
                    type: "success",
                    message: "Post published",
                };
            }
    
            return false;
        },
    });

4.27.0

Minor Changes

  • #4652 96af6d25b7a Thanks @alicanerdurmaz! - feat: added errros field to HttpError type. From now on, you can pass errors field to HttpError. This field will be used to update the useForm's error state.

    export interface ValidationErrors {
      [field: string]:
        | string
        | string[]
        | boolean
        | { key: string; message: string };
    }
    
    export interface HttpError extends Record<string, any> {
      message: string;
      statusCode: number;
      errors?: ValidationErrors;
    }

    Usage example:

    import { HttpError } from "@refinedev/core";
    
    const App = () => {
      return (
        <Refine
          routerProvider={routerProvider}
          dataProvider={{
            // ...
            update: async () => {
              // assume that the server returns the following error
              const error: HttpError = {
                message: "An error occurred while updating the record.",
                statusCode: 400,
                //This field will be used to update the `useForm`'s error state
                errors: {
                  title: [
                    "Title is required.",
                    "Title should have at least 5 characters.",
                  ],
                  "category.id": ["Category is required."],
                  status: true,
                  content: {
                    key: "form.error.content",
                    message: "Content is required.",
                  },
                },
              };
    
              return Promise.reject(error);
            },
          }}
        >
          {/* ... */}
        </Refine>
      );
    };

    Refer to the server-side form validation documentation for more information. →

  • #4652 96af6d25b7a Thanks @alicanerdurmaz! - feat: added disableServerSideValidation to the refine options for globally disabling server-side validation.

    import { Refine } from "@refinedev/core";
    
    <Refine
      options={{
        disableServerSideValidation: true,
      }}
    >
      // ...
    </Refine>;
  • #4591 f8891ead2bd Thanks @yildirayunlu! - feat: autoSave feature for useForm hook now accept autoSave object. enabled is a boolean value and debounce is a number value in milliseconds. debounce is optional and default value is 1000. autoSaveProps is an object that contains data, error and status values. data is the saved data, error is the error object and status is the status of the request. status can be loading, error, idle and success.

    const { autoSaveProps } = useForm({
        autoSave: {
            enabled: true,
            debounce: 2000, // not required, default is 1000
        },
    });

Patch Changes

  • #4659 3af99896101 Thanks @salihozdemir! - chore: fix tsdoc description of onCancel property on following hooks:

    • useUpdate
    • useUpdateMany
    • useDelete
    • useDeleteMany
  • #4665 3442f4bd00a Thanks @yildirayunlu! - feat: add false return type on SuccessErrorNotification

    This issue has been fixed in this PR, where the successNotification and errorNotification methods can now return false when a callback function is given. This allows the conditional notification to be displayed.

    const { mutate } = useCreate<IPost>({});
    
    mutate({
        resource: "posts",
        values: {
            title: "Hello World",
            status: "published",
        },
        successNotification: (data) => {
            if (data?.data.status === "published") {
                return {
                    type: "success",
                    message: "Post published",
                };
            }
    
            return false;
        },
    });

4.26.4

Patch Changes

  • #4626 03597ed8a9a Thanks @aliemir! - Added resource sanitization to the useCanWithoutCache hook to avoid cyclic value errors.

4.26.3

Patch Changes

  • #4626 03597ed8a9a Thanks @aliemir! - Added resource sanitization to the useCanWithoutCache hook to avoid cyclic value errors.

4.26.2

Patch Changes

4.26.1

Patch Changes

4.26.0

Minor Changes

  • #4568 8c2b3be35b0 Thanks @salihozdemir! - feat: add the textTransformers option to <Refine/> component

    The textTransformers option in refine is used to transform the resource name displayed on the user interface (UI). By default, if you define a resource named posts, refine will display it as Posts. Similarly, when you delete a record, notification messages will be shown as Post deleted successfully..

    You have the flexibility to customize these messages by using the textTransformers option. For instance, if you wish to disable any transformation, you can set the textTransformers option as shown in the example below:

    const App: React.FC = () => (
      <Refine
        // ...
        options={{
          textTransformers: {
            humanize: (text) => text,
            plural: (text) => text,
            singular: (text) => text,
          },
        }}
      />
    );

Patch Changes

  • #4583 c3c0deed564 Thanks @aliemir! - Added the missing resource property in params of the useCan call, which was leading to missing resource details in the access control checks in the can function.

    The provided resource item is sanitized to remove non-serializable properties such as icon etc. If you need such items, you should try to access your resource item directly from your defitinions.

  • #4599 5bb6f47a4d4 Thanks @aliemir! - Update default document title generation to use the fallback title when i18n's translate function returns the key value.

4.25.1

Patch Changes

  • #4599 5bb6f47a4d4 Thanks @aliemir! - Update default document title generation to use the fallback title when i18n's translate function returns the key value.

4.25.0

Minor Changes

  • #4568 8c2b3be35b0 Thanks @salihozdemir! - feat: add the textTransformers option to <Refine/> component

    The textTransformers option in refine is used to transform the resource name displayed on the user interface (UI). By default, if you define a resource named posts, refine will display it as Posts. Similarly, when you delete a record, notification messages will be shown as Post deleted successfully..

    You have the flexibility to customize these messages by using the textTransformers option. For instance, if you wish to disable any transformation, you can set the textTransformers option as shown in the example below:

    const App: React.FC = () => (
      <Refine
        // ...
        options={{
          textTransformers: {
            humanize: (text) => text,
            plural: (text) => text,
            singular: (text) => text,
          },
        }}
      />
    );

Patch Changes

  • #4583 c3c0deed564 Thanks @aliemir! - Added the missing resource property in params of the useCan call, which was leading to missing resource details in the access control checks in the can function.

    The provided resource item is sanitized to remove non-serializable properties such as icon etc. If you need such items, you should try to access your resource item directly from your defitinions.

4.24.0

Minor Changes

  • #4523 18d446b1069 Thanks @yildirayunlu! - feat: add useLoadingOvertime hook and implement primitive hooks

    If you need to do something when the loading time exceeds the specified time, refine provides the useLoadingOvertime hook. It returns the elapsed time in milliseconds.

    const { elapsedTime } = useLoadingOvertime({
      isLoading,
      interval: 1000,
      onInterval(elapsedInterval) {
        console.log("loading overtime", elapsedInterval);
      },
    });
    
    console.log(elapsedTime); // 1000, 2000, 3000, ...

    This hook implements the primitive data hooks:

  • #4527 ceadcd29fc9 Thanks @salihozdemir! - fix: support multiple resource usage with the same name via the identifier

    Previously, data hooks only worked with resource name. So if you had multiple resource usage with the same name, it would cause issues.

    Now the following hooks and its derivatives support identifier to distinguish between the resources:

    • useList
    • useInfiniteList
    • useOne
    • useMany
    • useCreate
    • useCreateMany
    • useUpdate
    • useUpdateMany
    • useDelete
    • useDeleteMany

    fix: generate correct queryKey's for queries with identifier

    Previously, the queryKey was generated using name. This caused issues when you had multiple resource usage with the same name. Now the queryKey's are generated using identifier if it's present.

  • #4523 18d446b1069 Thanks @yildirayunlu! - feat: add useLoadingOvertime hook

    if you need to do something when the loading time exceeds the specified time, refine provides the useLoadingOvertime hook. It returns the elapsed time in milliseconds.

    const { elapsedTime } = useLoadingOvertime({
      isLoading,
      interval: 1000,
      onInterval(elapsedInterval) {
        console.log("loading overtime", elapsedInterval);
      },
    });

    interval and onInterval are optional. It can be controlled globally from <Refine /> options.

    <Refine
        //...
        options={{
            //...
            overtime: {
                interval: 2000, // default 1000
                onInterval(elapsedInterval) {
                    console.log(
                        "loading overtime",
                        elapsedInterval,
                    );
                },
            },
        }}
    >

4.23.0

Minor Changes

  • #4523 18d446b1069 Thanks @yildirayunlu! - feat: add useLoadingOvertime hook and implement primitive hooks

    If you need to do something when the loading time exceeds the specified time, refine provides the useLoadingOvertime hook. It returns the elapsed time in milliseconds.

    const { elapsedTime } = useLoadingOvertime({
      isLoading,
      interval: 1000,
      onInterval(elapsedInterval) {
        console.log("loading overtime", elapsedInterval);
      },
    });
    
    console.log(elapsedTime); // 1000, 2000, 3000, ...

    This hook implements the primitive data hooks:

  • #4527 ceadcd29fc9 Thanks @salihozdemir! - fix: support multiple resource usage with the same name via the identifier

    Previously, data hooks only worked with resource name. So if you had multiple resource usage with the same name, it would cause issues.

    Now the following hooks and its derivatives support identifier to distinguish between the resources:

    • useList
    • useInfiniteList
    • useOne
    • useMany
    • useCreate
    • useCreateMany
    • useUpdate
    • useUpdateMany
    • useDelete
    • useDeleteMany

    fix: generate correct queryKey's for queries with identifier

    Previously, the queryKey was generated using name. This caused issues when you had multiple resource usage with the same name. Now the queryKey's are generated using identifier if it's present.

  • #4523 18d446b1069 Thanks @yildirayunlu! - feat: add useLoadingOvertime hook

    if you need to do something when the loading time exceeds the specified time, refine provides the useLoadingOvertime hook. It returns the elapsed time in milliseconds.

    const { elapsedTime } = useLoadingOvertime({
      isLoading,
      interval: 1000,
      onInterval(elapsedInterval) {
        console.log("loading overtime", elapsedInterval);
      },
    });

    interval and onInterval are optional. It can be controlled globally from <Refine /> options.

    <Refine
        //...
        options={{
            //...
            overtime: {
                interval: 2000, // default 1000
                onInterval(elapsedInterval) {
                    console.log(
                        "loading overtime",
                        elapsedInterval,
                    );
                },
            },
        }}
    >

4.22.0

Minor Changes

  • #4449 cc84d61bc5c Thanks @BatuhanW! - feat: allow access control provider to be configured globally.

    Now accessControlProvider accepts options.buttons parameter to globally configure UI buttons' behaviour.

    These configuration will be used as a fallback, if no configuration on button prop level is found.

    Default values:

    options.buttons.enableAccessControl => true options.buttons.hideIfUnauthorized => false

    const accessControlProvider: IAccessControlContext = {
      can: async (params: CanParams): Promise<CanReturnType> => {
        return { can: true };
      },
      options: {
        buttons: {
          enableAccessControl: true,
          hideIfUnauthorized: false,
        },
      },
    };

Patch Changes

  • #4521 a3c8d4f84c7 Thanks @alicanerdurmaz! - fixed: useExport's resource props is not working. With this fix, useExport will now work with resource props.

    useExport({
      resource: "users",
    });

4.21.0

Minor Changes

  • #4449 cc84d61bc5c Thanks @BatuhanW! - feat: allow access control provider to be configured globally.

    Now accessControlProvider accepts options.buttons parameter to globally configure UI buttons' behaviour.

    These configuration will be used as a fallback, if no configuration on button prop level is found.

    Default values:

    options.buttons.enableAccessControl => true options.buttons.hideIfUnauthorized => false

    const accessControlProvider: IAccessControlContext = {
      can: async (params: CanParams): Promise<CanReturnType> => {
        return { can: true };
      },
      options: {
        buttons: {
          enableAccessControl: true,
          hideIfUnauthorized: false,
        },
      },
    };

Patch Changes

  • #4521 a3c8d4f84c7 Thanks @alicanerdurmaz! - fixed: useExport's resource props is not working. With this fix, useExport will now work with resource props.

    useExport({
      resource: "users",
    });

4.20.0

Minor Changes

  • #4448 c82006f712a Thanks @BatuhanW! - feat: useApiUrl hook tries to infer data provider from current resource. If current resource has a different data provider than the default one, it will be inferred without needing to explicitly pass data provider name.

4.19.0

Minor Changes

  • #4448 c82006f712a Thanks @BatuhanW! - feat: useApiUrl hook tries to infer data provider from current resource. If current resource has a different data provider than the default one, it will be inferred without needing to explicitly pass data provider name.

4.18.2

Patch Changes

  • #4446 5936d9cd4d4 Thanks @salihozdemir! - refactor: increase accessibility of auth page components

    add htmlFor to label elements to associate them with their inputs

4.18.1

Patch Changes

  • #4446 5936d9cd4d4 Thanks @salihozdemir! - refactor: increase accessibility of auth page components

    add htmlFor to label elements to associate them with their inputs

4.18.0

Minor Changes

  • #4430 cf07d59587f Thanks @aliemir! - Added queryMeta and mutationMeta properties to the useForm hook. These properties are used to pass specific meta values to the query or mutation. This is useful when you have overlapping values in your data provider's getOne and update methods. For example, you may want to change the method of the mutation to PATCH but if you pass it in the meta property, you'll end up changing the method of the getOne request as well.

    queryMeta and mutationMeta has precedence over meta. This means that if you have the same property in queryMeta and meta, the value in queryMeta will be used.

    Usage

    import { useForm } from "@refinedev/core";
    
    export const MyEditPage = () => {
      const form = useForm({
        // this is passed both to the mutation and the query requests
        meta: {
          myValue: "myValue",
        },
        // this is only passed to the query request
        queryMeta: {
          propertyOnlyWorksForQuery: "propertyOnlyWorksForQuery",
        },
        // this is only passed to the mutation request
        mutationMeta: {
          propertyOnlyWorksForMutation: "propertyOnlyWorksForMutation",
        },
      });
    };

Patch Changes

4.17.0

Minor Changes

  • #4430 cf07d59587f Thanks @aliemir! - Added queryMeta and mutationMeta properties to the useForm hook. These properties are used to pass specific meta values to the query or mutation. This is useful when you have overlapping values in your data provider's getOne and update methods. For example, you may want to change the method of the mutation to PATCH but if you pass it in the meta property, you'll end up changing the method of the getOne request as well.

    queryMeta and mutationMeta has precedence over meta. This means that if you have the same property in queryMeta and meta, the value in queryMeta will be used.

    Usage

    import { useForm } from "@refinedev/core";
    
    export const MyEditPage = () => {
      const form = useForm({
        // this is passed both to the mutation and the query requests
        meta: {
          myValue: "myValue",
        },
        // this is only passed to the query request
        queryMeta: {
          propertyOnlyWorksForQuery: "propertyOnlyWorksForQuery",
        },
        // this is only passed to the mutation request
        mutationMeta: {
          propertyOnlyWorksForMutation: "propertyOnlyWorksForMutation",
        },
      });
    };

Patch Changes

4.16.4

Patch Changes

4.16.3

Patch Changes

4.16.2

Patch Changes

  • #4407 473bbe5b31d Thanks @aliemir! - Added missing clone action for document title generation. This fixes the issue of the document title not being generated when the clone action is used.

    This change introduces the documentTitle.{resourceName}.clone key to the list of i18n keys that are used to generate the document title.

    Default title for the clone action is "#{{id}} Clone {{resourceName}} | refine".

  • #4407 473bbe5b31d Thanks @aliemir! - Fixed the issue of label not taken into account with auto generated document titles. label will be prioritized over the resource name when generating the document title and the label will not be capitalized.

4.16.1

Patch Changes

  • #4407 473bbe5b31d Thanks @aliemir! - Added missing clone action for document title generation. This fixes the issue of the document title not being generated when the clone action is used.

    This change introduces the documentTitle.{resourceName}.clone key to the list of i18n keys that are used to generate the document title.

    Default title for the clone action is "#{{id}} Clone {{resourceName}} | refine".

  • #4407 473bbe5b31d Thanks @aliemir! - Fixed the issue of label not taken into account with auto generated document titles. label will be prioritized over the resource name when generating the document title and the label will not be capitalized.

4.16.0

Minor Changes

  • #4313 28fe67047a0 Thanks @abdellah711! - feat: implement generateDefaultDocumentTitle function

    This function generates a default document title based on the current route by following these rules (resource in this case is "Post"):

    • list -> Posts | refine
    • edit -> #{id} Edit Post | refine
    • show -> #{id} Show Post | refine
    • create -> Create new Post | refine
    • default (not a resource) -> refine

Patch Changes

4.15.0

Minor Changes

  • #4313 28fe67047a0 Thanks @abdellah711! - feat: implement generateDefaultDocumentTitle function

    This function generates a default document title based on the current route by following these rules (resource in this case is "Post"):

    • list -> Posts | refine
    • edit -> #{id} Edit Post | refine
    • show -> #{id} Show Post | refine
    • create -> Create new Post | refine
    • default (not a resource) -> refine

Patch Changes

4.14.3

Patch Changes

4.14.2

Patch Changes

4.14.1

Patch Changes

4.14.0

Minor Changes

  • #4241 fbe109b5a8b Thanks @salihozdemir! - Added new generic types to the useForm hooks. Now you can pass the query types and the mutation types to the hook.

    import { useForm } from "@refinedev/core";
    
    useForm<TQueryFnData, TError, TVariables, TData, TResponse, TResponseError>();

4.13.0

Minor Changes

  • #4241 fbe109b5a8b Thanks @salihozdemir! - Added new generic types to the useForm hooks. Now you can pass the query types and the mutation types to the hook.

    import { useForm } from "@refinedev/core";
    
    useForm<TQueryFnData, TError, TVariables, TData, TResponse, TResponseError>();

4.12.0

Minor Changes

  • #4194 8df15fe0e4e Thanks @alicanerdurmaz! - feat: sorters.mode prop added to useTable and useDataGrid hooks. This prop handles the sorting mode of the table. It can be either server or off.

    • "off": sorters are not sent to the server. You can use the sorters value to sort the records on the client side.
    • "server": Sorting is done on the server side. Records will be fetched by using the sorters value.

    feat:filters.mode prop added to useTable and useDataGrid hooks. This prop handles the filtering mode of the table. It can be either server or off.

    • "off": filters are not sent to the server. You can use the filters value to filter the records on the client side.
    • "server": Filtering is done on the server side. Records will be fetched by using the filters value.

Patch Changes

4.11.0

Minor Changes

  • #4194 8df15fe0e4e Thanks @alicanerdurmaz! - feat: sorters.mode prop added to useTable and useDataGrid hooks. This prop handles the sorting mode of the table. It can be either server or off.

    • "off": sorters are not sent to the server. You can use the sorters value to sort the records on the client side.
    • "server": Sorting is done on the server side. Records will be fetched by using the sorters value.

    feat:filters.mode prop added to useTable and useDataGrid hooks. This prop handles the filtering mode of the table. It can be either server or off.

    • "off": filters are not sent to the server. You can use the filters value to filter the records on the client side.
    • "server": Filtering is done on the server side. Records will be fetched by using the filters value.

Patch Changes

4.10.0

Minor Changes

  • #4135 e72c0d2b41f Thanks @salihozdemir! - feat: Expose the query params to the meta and add the ability to pass global meta to data provider methods

    • Added the ability to pass meta to data provider methods globally for specific resources.

      For example, to pass the role property to all data provider methods for the posts resource, use the following code:

      import { Refine } from "@refinedev/core";
      
      const App: React.FC = () => {
        return (
          <Refine
            resources={[
              {
                name: "posts",
                meta: {
                  role: "editor",
                },
              },
            ]}
          />
        );
      };

      Now, when you call any data hook with the posts resource, the meta property will be accessible in the data provider methods.

      const dataProvider = {
        getList: async ({ resource, meta }) => {
          console.log(meta.role); // "editor"
        },
      };
    • Added the query params to the meta property by default.

      For example, if you call the useList hook on the example.com/posts?status=published URL, the meta property will be accessible in the data provider methods as follows:

      const dataProvider = {
        getList: async ({ resource, meta }) => {
          console.log(meta.status); // "published"
        },
      };

Patch Changes

  • #4159 f7f590589e7 Thanks @aliemir! - fixed: missing resource meta in route compositions

    Added missing resource meta values when composing routes. This fixes the bug where the resource meta values does not included in the route composition.

4.9.0

Minor Changes

  • #4135 e72c0d2b41f Thanks @salihozdemir! - feat: Expose the query params to the meta and add the ability to pass global meta to data provider methods

    • Added the ability to pass meta to data provider methods globally for specific resources.

      For example, to pass the role property to all data provider methods for the posts resource, use the following code:

      import { Refine } from "@refinedev/core";
      
      const App: React.FC = () => {
        return (
          <Refine
            resources={[
              {
                name: "posts",
                meta: {
                  role: "editor",
                },
              },
            ]}
          />
        );
      };

      Now, when you call any data hook with the posts resource, the meta property will be accessible in the data provider methods.

      const dataProvider = {
        getList: async ({ resource, meta }) => {
          console.log(meta.role); // "editor"
        },
      };
    • Added the query params to the meta property by default.

      For example, if you call the useList hook on the example.com/posts?status=published URL, the meta property will be accessible in the data provider methods as follows:

      const dataProvider = {
        getList: async ({ resource, meta }) => {
          console.log(meta.status); // "published"
        },
      };

Patch Changes

  • #4159 f7f590589e7 Thanks @aliemir! - fixed: missing resource meta in route compositions

    Added missing resource meta values when composing routes. This fixes the bug where the resource meta values does not included in the route composition.

4.8.5

Patch Changes

4.8.4

Patch Changes

4.8.3

Patch Changes

4.8.2

Patch Changes

4.8.1

Patch Changes

4.8.0

Minor Changes

  • #4113 1c13602e308 Thanks @salihozdemir! - Added missing third generic parameter to hooks which are using useQuery internally.

    For example:

    import { useOne, HttpError } from "@refinedev/core";
    
    const { data } = useOne<{ count: string }, HttpError, { count: number }>({
      resource: "product-count",
      queryOptions: {
        select: (rawData) => {
          return {
            data: {
              count: Number(rawData?.data?.count),
            },
          };
        },
      },
    });
    
    console.log(typeof data?.data.count); // number

Patch Changes

  • #4129 e64ffe999b3 Thanks @aliemir! - Added the missing connection between the data provider's and the useMany hook's meta property.

  • #4113 1c13602e308 Thanks @salihozdemir! - Updated the generic type name of hooks that use useQuery to synchronize generic type names with tanstack-query.

4.7.2

Patch Changes

4.7.1

Patch Changes

4.7.0

Minor Changes

Patch Changes

4.6.0

Minor Changes

Patch Changes

4.5.10

Patch Changes

  • #4035 e0c75450f97 Thanks @salihozdemir! - Add types for notification methods arguments based on given generic types.

  • #4071 98cd4b0f203 Thanks @salihozdemir! - Update authBindings error type to provide changeable error messages on notifcations.

    Example for login method:

    import { AuthBindings } from "@refinedev/core";
    
    const authProvider: AuthBindings = {
        login: async ({ email, password }) => {
            ...
            return {
                success: false,
                error: {
                    message: "Login Failed!",
                    name:
                        "The email or password that you've entered doesn't match any account.",
                },
            };
        },
        ...
    };

4.5.9

Patch Changes

  • #4035 e0c75450f97 Thanks @salihozdemir! - Add types for notification methods arguments based on given generic types.

  • #4071 98cd4b0f203 Thanks @salihozdemir! - Update authBindings error type to provide changeable error messages on notifcations.

    Example for login method:

    import { AuthBindings } from "@refinedev/core";
    
    const authProvider: AuthBindings = {
        login: async ({ email, password }) => {
            ...
            return {
                success: false,
                error: {
                    message: "Login Failed!",
                    name:
                        "The email or password that you've entered doesn't match any account.",
                },
            };
        },
        ...
    };

4.5.8

Patch Changes

  • #4014 3db450fade0 Thanks @salihozdemir! - Add console warning for useForm and useShow hooks when custom resource is provided and id prop is not passed.

4.5.7

Patch Changes

  • #4014 3db450fade0 Thanks @salihozdemir! - Add console warning for useForm and useShow hooks when custom resource is provided and id prop is not passed.

4.5.6

Patch Changes

4.5.5

Patch Changes

4.5.4

Patch Changes

4.5.3

Patch Changes

4.5.2

Patch Changes

  • #3911 5f9c70ebf2f Thanks @salihozdemir! - In forms that use useForm, the onFinish was resetting the current id to undefined when the mutation is successful. Now, the id will not be set to undefined.

4.5.1

Patch Changes

  • #3911 5f9c70ebf2f Thanks @salihozdemir! - In forms that use useForm, the onFinish was resetting the current id to undefined when the mutation is successful. Now, the id will not be set to undefined.

4.5.0

Minor Changes

  • #3912 0ffe70308b2 Thanks @alicanerdurmaz! - - title prop added to AuthPage's renderContent prop to use in the custom content.
    • title prop added to AuthPage to render a custom title.
      • ⚠️ These features have not been implemented yet. Only types were added. It will be implemented in the next release.

4.4.0

Minor Changes

  • #3912 0ffe70308b2 Thanks @alicanerdurmaz! - - title prop added to AuthPage's renderContent prop to use in the custom content.
    • title prop added to AuthPage to render a custom title.
      • ⚠️ These features have not been implemented yet. Only types were added. It will be implemented in the next release.

4.3.0

Minor Changes

  • #3892 41a4525454c Thanks @BatuhanW! - feat: make CanAccess component props optional. Now CanAccess component infers resource and action automagically.

4.2.0

Minor Changes

  • #3892 41a4525454c Thanks @BatuhanW! - feat: make CanAccess component props optional. Now CanAccess component infers resource and action automagically.

4.1.6

Patch Changes

  • #3890 db12d60095f Thanks @aliemir! - - Fixed layout flickering on authenticated routes.
    • Fixed repeated navigations issue on routes with <Authenticated> component.
    • Fixed conflicting navigation paths with authProvider methods and <Authenticated> component.

4.1.5

Patch Changes

  • #3890 db12d60095f Thanks @aliemir! - - Fixed layout flickering on authenticated routes.
    • Fixed repeated navigations issue on routes with <Authenticated> component.
    • Fixed conflicting navigation paths with authProvider methods and <Authenticated> component.

4.1.4

Patch Changes

4.1.3

Patch Changes

4.1.2

Patch Changes

4.1.1

Patch Changes

4.1.0

Minor Changes

  • Thanks @aliemir, @alicanerdurmaz, @batuhanW, @salihozdemir, @yildirayunlu, @recepkutuk!

    🪄 Migrating your project automatically with refine-codemod ✨

    @refinedev/codemod package handles the breaking changes for your project automatically, without any manual steps. It migrates your project from 3.x.x to 4.x.x.

    Just cd into root folder of your project (where package.json is contained) and run this command:

    npx @refinedev/codemod@latest refine3-to-refine4

    And it's done. Now your project uses `refine@4.x.x`.

    📝 Changelog

    We're releasing a new way to connect routers to refine. Now the routerProvider prop is marked as optional in <Refine> component.

    New routerProvider property is smaller and more flexible than the previous one which is now can be used with legacyRouterProvider property.

    We've redesigned our bindings to the router libraries. Instead of handling the route creation process, now refine leaves this to the user and only uses a way to communicate with the router and the routes through the bindings provided to routerProvider property.

    The changes in routing system comes with a new way to define resource actions as well. Actions now can be defined as paths, components or both. We're encouraging our users to use paths, which enables our users to use all the optimizations that the router libraries provide without giving up any features of refine.

    Router libraries are also comes with components like RefineRoutes which can be used to define routes for resources when you pass components to the actions of the resources. Please refer to the documentation for more information.

    Changes in resources

    Now you can define actions in multiple ways;

    1. As a path
    <Refine
      resources={[
        {
          name: "posts",
          list: "/posts",
        },
      ]}
    >
      ...
    </Refine>
    1. As a component
    import { PostList } from "src/posts";
    
    <Refine
      resources={[
        {
          name: "posts",
          list: PostList,
        },
      ]}
    >
      ...
    </Refine>;
    1. As both
    import { PostList } from "src/posts";
    
    <Refine
      resources={[
        {
          name: "posts",
          list: {
            path: "/posts",
            component: PostList,
          },
        },
      ]}
    >
      ...
    </Refine>;

    This also comes with some additional changes;

    • options property is renamed to meta for consistency.
    • parentName is now defined with parent property in meta object.
    • auditLog is renamed to audit.
    • route in options is now deprecated for the new routing system. If you want to define a custom route for a resource, you can define such routes in action definitions.
    • Parents are not included in the routes by default. If you want to inclue parents in the routes, you need to define action paths explicitly.
    • identifier can be passed to the resource definition to distinguish between resources with the same name. This is useful when you have multiple resources with the same name.

    Nested routes

    Now, refine supports nested routes with parameters. You can define the action paths for a resource with parameters. Parameters will be filled with the current ones in the URL and additional ones can be provided via meta properties in hooks and components.

    <Refine
        resources={[
            {
                name: "posts",
                list: "users/:authorId/posts",
                show: "users/:authorId/posts/:id",
            },
        ]}
    >

    When you're in the list page of the posts resource, assuming you already have the authorId parameter present in the URL, the show action will be rendered with the authorId parameter filled with the current one in the URL. If you want to use a different authorId, you can pass meta properties to the components or hooks, such as useGetToPath hook to get the navigation path.

    const { go } = useGo();
    const getToPath = useGetToPath();
    
    const to = getToPath({
      resource: "posts",
      action: "show",
      meta: {
        id: 1,
        authorId: 2,
      },
    });
    // "to" will be "/users/2/posts/1"
    
    go({ to, type: "push" });

    Changes in routerProvider

    routerProvider is now smaller and more flexible. It only contains the following properties;

    • Link: A component that accepts to prop and renders a link to the given path.
    • go: A function that returns a function that accepts a config object and navigates to the given path.
    • back: A function that returns a function that navigates back to the previous page.
    • parse: A function that returns a function that returns the resource, id, action and additional params from the given path. This is the refine's way to communicate with the router library.

    None of the properties are required. Missing properties may result in some features not working but it won't break refine.

    Our users are able to provide different implementations for the router bindings, such as handling the search params in the path with a different way or customizing the navigation process.

    Note: Existing routerProvider implementation is preserved as legacyRouterProvider and will continue working as before. We're planning to remove it in the next major version.

    Note: New routing system do not handle the authentication process. You can now wrap your components with Authenticated component or handle the authentication check inside your components through useIsAuthenticated hook to provide more flexible auth concepts in your app.

    Changes in hooks

    We're now providing new hooks for the new routing system. You're free to use them or use the ones provided by your router library.

    • useGo
    • useBack
    • useParsed
    • useLink
    • useGetToPath

    are provided by refine to use the properties of routerProvider in a more convenient way.

    • useResourceWithRoute is now deprecated and only works with the legacy routing system.
    • useResource has changed its definition and now accepts a single argument which is the resource name. It returns the resource object depending on the current route or the given resource name. If resource is provided but not found, it will create a temporary one to use with the given resource name.
    • useNavigation's functions in its return value are now accepting meta object as an argument. This can be used to provide parameters to the target routes. For example, if your path for the edit action of a resource is /:userId/posts/:id/edit, you can provide userId parameter in meta object and it will be used in the path.
    • Hooks using routes, redirection etc. are now accepts meta property in their arguments. This can be used to provide parameters to the target routes. This change includes useMenu and useBreadcrumb which are creating paths to the resources for their purposes.
    • selectedKey in useMenu hook's return type now can be undefined if the current route is not found in the menu items.

    warnWhenUnsavedChanges prop

    In earlier versions, refine was handling this feature in beforeunload event. This was causing unintended dependencies to the window and was not customizable. Now, refine is leaving this to the router libraries. Router packages @refinedev/react-router-v6, @refinedev/nextjs-router and @refinedev/remix-router are now exporting a component UnsavedChangesNotifier which can be placed under the <Refine> component and registers a listener to the necessary events to handle the warnWhenUnsavedChanges feature.

    Changes in Authenticated component.

    <Authenticated> component now accepts redirectOnFail to override the redirection path on authentication failure. This can be used to redirect to a different page when the user is not authenticated. This property only works if the fallback prop is not provided.

    redirectOnFail also respects the newly introduced appendCurrentPathToQuery prop which can be used to append the current path to the query string of the redirection path. This can be used to redirect the user to the page they were trying to access after they logged in.

    Changes in <Refine>

    We've removed the long deprecated props from <Refine /> component and deprecated some more to encourage users to use the new routing system.

    In earlier versions, we've accepted layout related props such as Layout, Sider, Header, Footer, OffLayoutArea and Title. All these props were used in the route creation process while wrapping the components to the Layout and others were passed to the Layout for configuration. Now, we've deprecated these props and we're encouraging users to use Layout prop and its props in the children of <Refine /> component. This will allow users to customize the layout easily and provide custom layouts per route.

    We've also deprecated the route related props such as;

    • catchAll, which was used in rendering 404 pages and was unclear to the user when its going to be rendered in the app.
    • LoginPage, which was rendered at /login path and was not customizable enough.
    • DashboardPage, which wass rendered at / path and was limiting our users to handle the index page just with a single prop.
    • ReadyPage, which was shown when <Refine> had no resources defined. Now, we're accepting empty resources array and rendering nothing in this case.

    We're encouraging our users to create their own routes for the above props and give them the flexibility to use the full potential of the router library they're using.

    Integration with existing apps

    We've made the changes to the routing system, the resource definitions and some additional changes to make the integration with existing apps possible.

    Now you can migrate your existing apps to refine with ease and incrementally adopt refine's features.

    Backward compatibility

    We've made all the changes in a backward compatible way. You can continue using the old routing system and the old props of <Refine /> component. Migrating to the new behaviors are optional but encouraged.

    We're planning to keep the support for the deprecated props and the old behaviors until the next major version.

  • Thanks @aliemir, @alicanerdurmaz, @batuhanW, @salihozdemir, @yildirayunlu, @recepkutuk! Added audit log support for the following hooks:

  • Thanks @aliemir, @alicanerdurmaz, @batuhanW, @salihozdemir, @yildirayunlu, @recepkutuk! Added a helper function to pick not deprecated value. Gives priority according to the order of the arguments.

    const sorter = undefined;
    const sorters = [{ id: 1 }];
    
    const value = pickNotDeprecated(sorter, sorters) ?? 10; // [{ id: 1 }]
  • Thanks @aliemir, @alicanerdurmaz, @batuhanW, @salihozdemir, @yildirayunlu, @recepkutuk!

    useList hook

    • Added default value for pagination.current property. It is set to 1.
    • Added default value for pagination.pageSize property. It is set to 10.
    • Added pagination.mode property. By default, it is "server".
      • When it is "off", all records will be fetched from the API.
      • When it is "client", all records will be fetched from the API and pagination will be handled by the useList hook.
      • When it is "server", pagination will be handled by the API using current and pageSize properties of your pagination object.

    useTable hook

    useTable return values and properties are updated.

    • initialCurrent and initialPageSize props are now deprecated. Use pagination prop instead.
    • To ensure backward compatibility, initialCurrent and initialPageSize props will work as before.

      useTable({
      -    initialCurrent,
      -    initialPageSize,
      +    pagination: {
      +        current,
      +        pageSize,
      +    },
      })
    • hasPagination prop is now deprecated. Use pagination.mode instead.

    • To ensure backward compatibility, hasPagination prop will work as before.

      useTable({
      -    hasPagination,
      +    pagination: {
      +        mode: "off" | "server" | "client",
      +    },
      })
    • initialSorter and permanentSorter props are now deprecated. Use sorters.initial and sorters.permanent instead.

    • To ensure backward compatibility, initialSorter and permanentSorter props will work as before.

      useTable({
      -    initialSorter,
      -    permanentSorter,
      +    sorters: {
      +        initial,
      +        permanent,
      +    },
      })
    • initialFilter, permanentFilter, and defaultSetFilterBehavior props are now deprecated. Use filters.initial, filters.permanent, and filters.defaultBehavior instead.

    • To ensure backward compatibility, initialFilter, permanentFilter, and defaultSetFilterBehavior props will work as before.

      useTable({
      -    initialFilter,
      -    permanentFilter,
      -    defaultSetFilterBehavior,
      +    filters: {
      +        initial,
      +        permanent,
      +        defaultBehavior,
      +    },
      })
    • sorter and setSorter return values are now deprecated. Use sorters and setSorters instead.

    • To ensure backward compatibility, sorter and setSorter return values will work as before.

      const {
      -   sorter,
      +   sorters,
      -   setSorter,
      +   setSorters,
      } = useTable();
  • Thanks @aliemir, @alicanerdurmaz, @batuhanW, @salihozdemir, @yildirayunlu, @recepkutuk! All @tanstack/react-query imports re-exported from @refinedev/core have been removed. You should import them from @tanstack/react-query package directly.

    If the package is not installed, you can install it with your package manager:

    npm install @tanstack/react-query
    # or
    pnpm add @tanstack/react-query
    # or
    yarn add @tanstack/react-query

    After that, you can import them from @tanstack/react-query package directly instead of @refinedev/core package.

    - import { QueryClient } from "@refinedev/core";
    
    + import { QueryClient } from "@tanstack/react-query";
  • Thanks @aliemir, @alicanerdurmaz, @batuhanW, @salihozdemir, @yildirayunlu, @recepkutuk!

    • options prop of resource is now deprecated. Use meta prop instead.
    • To ensure backward compatibility, options prop will be used if meta prop is not provided.
    <Refine
        resources={[
            {
                name: "posts",
    -           options: {},
    +           meta: {},
            },
        ]}
    />
  • Thanks @aliemir, @alicanerdurmaz, @batuhanW, @salihozdemir, @yildirayunlu, @recepkutuk!

    • AuthProvider deprecated and renamed to LegacyAuthProvider.
    • legacyAuthProvider prop is added to <Refine> component for backward compatibility.
    • legacy prop added to auth hooks support AuthProvider and LegacyAuthProvider.
  • Thanks @aliemir, @alicanerdurmaz, @batuhanW, @salihozdemir, @yildirayunlu, @recepkutuk!

    • <ReadyPage> isnow deprecated.
    • Created a <WelcomePage> component to welcome users.
  • Thanks @aliemir, @alicanerdurmaz, @batuhanW, @salihozdemir, @yildirayunlu, @recepkutuk!

    • useList and useInfiniteList's config prop is now deprecated. Use sorters, filters, pagination and hasPagination props instead.
    useList({
    -    config: {
    -        sort,
    -        filters,
    -        pagination,
    -        hasPagination,
    -    },
    +    sorters,
    +    filters,
    +    pagination,
    +    hasPagination,
    })
    
    useInfiniteList({
    -    config: {
    -        sort,
    -        filters,
    -        pagination,
    -        hasPagination,
    -    },
    +    sorters,
    +    filters,
    +    pagination,
    +    hasPagination,
    })
    • useImport and useExport's resourceName prop is now deprecated. Use resource prop instead.
    useImport({
    -    resourceName,
    +    resource,
    })
    
    useExport({
    -    resourceName,
    +    resource,
    })
    • useExport's sorter prop is now deprecated. Use sorters prop instead.
    useExport({
    -    sorter,
    +    sorters,
    })
    • useSelect's sort prop is now deprecated. Use sorters prop instead.
    useSelect({
    -    sort,
    +    sorters,
    })
    • useSelect's config.sort prop is now deprecated. Use config.sorters prop instead.
    useCustom({
        config: {
    -       sort,
    +       sorters,
        }
    })
  • Thanks @aliemir, @alicanerdurmaz, @batuhanW, @salihozdemir, @yildirayunlu, @recepkutuk! hasPagination default value set to false on useSelect. So all of the records will be fetched by default.

  • Thanks @aliemir, @alicanerdurmaz, @batuhanW, @salihozdemir, @yildirayunlu, @recepkutuk! Updated useSelect hook to support optionLabel and optionValue type as keyof TData instead of string.

    So optionLabel and optionValue have an interface based on the given TData type.

    - optionLabel?: string;
    - optionValue?: string;
    + optionLabel?: keyof TData extends string ? keyof TData : never;
    + optionValue?: keyof TData extends string ? keyof TData : never;
  • Thanks @aliemir, @alicanerdurmaz, @batuhanW, @salihozdemir, @yildirayunlu, @recepkutuk! Moving to the @refinedev scope 🎉🎉

    Moved to the @refinedev scope and updated our packages to use the new scope. From now on, all packages will be published under the @refinedev scope with their new names.

    Now, we're also removing the refine prefix from all packages. So, the @pankod/refine-core package is now @refinedev/core, @pankod/refine-antd is now @refinedev/antd, and so on.

Patch Changes

3.103.0

Minor Changes

3.102.0

Minor Changes

3.101.2

Patch Changes

3.101.1

Patch Changes

3.101.0

Minor Changes

3.100.0

Minor Changes

3.99.6

Patch Changes

  • #3657 5868456194f Thanks @fuunnx! - Fix optimistic updates of list's query data following a mutation using useUpdate

3.99.5

Patch Changes

  • #3657 5868456194f Thanks @fuunnx! - Fix optimistic updates of list's query data following a mutation using useUpdate

3.99.4

Patch Changes

3.99.3

Patch Changes

3.99.2

Patch Changes

3.99.1

Patch Changes

3.99.0

Minor Changes

3.98.0

Minor Changes

3.97.0

Minor Changes

  • #3442 8f2954611fa Thanks @salihozdemir! - Added swizzle support for @pankod/refine-core package.

    Swizzleable components:

    • Authenticated
    • CanAccess
    • ErrorPage
    • Authentication Pages
      • Login
      • Logout
      • Register
      • ForgotPassword
      • UpdatePassword

Patch Changes

3.96.0

Minor Changes

  • #3442 8f2954611fa Thanks @salihozdemir! - Added swizzle support for @pankod/refine-core package.

    Swizzleable components:

    • Authenticated
    • CanAccess
    • ErrorPage
    • Authentication Pages
      • Login
      • Logout
      • Register
      • ForgotPassword
      • UpdatePassword

Patch Changes

3.95.3

Patch Changes

  • #3382 6604586b030 Thanks @alicanerdurmaz! - Fixed: The link in the jsDOC of the liveMode replaced with the correct link.

    - * @type  [`"auto" | "manual" | "off"`](/docs/api-reference/core/interfaceReferences/#crudsorting)
    + * @type  [`"auto" | "manual" | "off"`](/docs/api-reference/core/providers/live-provider/#livemode)

3.95.2

Patch Changes

  • #3382 6604586b030 Thanks @alicanerdurmaz! - Fixed: The link in the jsDOC of the liveMode replaced with the correct link.

    - * @type  [`"auto" | "manual" | "off"`](/docs/api-reference/core/interfaceReferences/#crudsorting)
    + * @type  [`"auto" | "manual" | "off"`](/docs/api-reference/core/providers/live-provider/#livemode)

3.95.1

Patch Changes

3.95.0

Minor Changes

3.94.2

Patch Changes

  • #3364 98a1fbec65a Thanks @aliemir! - Changed IResourceComponents from IResourceContext to use React.ComponentType rather than React.FunctionComponent to make it compatible with other types and interfaces.

  • #3356 310ebd05990 Thanks @omeraplak! - Fixed checkError hook is not called in onError of useCustomMutation

3.94.1

Patch Changes

  • #3364 98a1fbec65a Thanks @aliemir! - Changed IResourceComponents from IResourceContext to use React.ComponentType rather than React.FunctionComponent to make it compatible with other types and interfaces.

  • #3356 310ebd05990 Thanks @omeraplak! - Fixed checkError hook is not called in onError of useCustomMutation

3.94.0

Minor Changes

3.93.0

Minor Changes

3.92.0

Minor Changes

  • #3324 9bfb34749bc Thanks @aliemir! - Added the ability to pass mutation options to useMutation hooks in mutation hooks:
    • useCreate (data)
    • useUpdate (data)
    • useDelete (data)
    • useDeleteMany (data)
    • useUpdateMany (data)
    • useCreateMany (data)
    • useCustomMutation (data)
    • useLogin (auth)
    • useLogout (auth)
    • useRegister (auth)
    • useForgotPassword (auth)
    • useUpdatePassword (auth)
    • useForm (form)

Patch Changes

3.91.0

Minor Changes

  • #3324 9bfb34749bc Thanks @aliemir! - Added the ability to pass mutation options to useMutation hooks in mutation hooks:
    • useCreate (data)
    • useUpdate (data)
    • useDelete (data)
    • useDeleteMany (data)
    • useUpdateMany (data)
    • useCreateMany (data)
    • useCustomMutation (data)
    • useLogin (auth)
    • useLogout (auth)
    • useRegister (auth)
    • useForgotPassword (auth)
    • useUpdatePassword (auth)
    • useForm (form)

Patch Changes

3.90.6

Patch Changes

3.90.5

Patch Changes

3.90.4

Patch Changes

  • #3098 a241ef3c957 Thanks @aliemir! - Update notificationProvider prop handling by converting to a custom hook to prevent hook usage errors.

3.90.3

Patch Changes

  • #3098 a241ef3c957 Thanks @aliemir! - Update notificationProvider prop handling by converting to a custom hook to prevent hook usage errors.

3.90.2

Patch Changes

3.90.1

Patch Changes

3.90.0

Minor Changes

3.89.0

Minor Changes

3.88.4

Patch Changes

3.88.3

Patch Changes

3.88.2

Patch Changes

3.88.1

Patch Changes

3.88.0

Minor Changes

  • #2872 da3fc4a702 Thanks @TDP17! - Feat: Added ability to manage breadcrumb component globally via options

    Usage

    <Refine
        options= {{
            breadcrumb: false, // hide globally
        }}
    />
    or
    ```jsx
    <Refine
        options= {{
            breadcrumb: <MyCustomBreadcrumbComponent /> // custom component
        }}
    />

3.87.0

Minor Changes

  • #2872 da3fc4a702 Thanks @TDP17! - Feat: Added ability to manage breadcrumb component globally via options

    Usage

    <Refine
        options= {{
            breadcrumb: false, // hide globally
        }}
    />
    or
    ```jsx
    <Refine
        options= {{
            breadcrumb: <MyCustomBreadcrumbComponent /> // custom component
        }}
    />

3.86.2

Patch Changes

  • #2839 5388a338ab Thanks @aliemir! - useCan hook was returning the stale value if same call is made with skipped access control.

3.86.1

Patch Changes

  • #2839 5388a338ab Thanks @aliemir! - useCan hook was returning the stale value if same call is made with skipped access control.

3.86.0

Minor Changes

  • Only or was supported as a conditional filter. Now and and or can be used together and nested. 🚀

    {
      operator: "or",
      value: [
        {
          operator: "and",
          value: [
            {
              field: "name",
              operator: "eq",
              value: "John Doe",
            },
            {
              field: "age",
              operator: "eq",
              value: 30,
            },
          ],
        },
        {
          operator: "and",
          value: [
            {
              field: "name",
              operator: "eq",
              value: "JR Doe",
            },
            {
              field: "age",
              operator: "eq",
              value: 1,
            },
          ],
        },
      ],
    }

3.85.0

Minor Changes

  • #2751 addff64c77 Thanks @yildirayunlu! - Only or was supported as a conditional filter. Now and and or can be used together and nested. 🚀

    {
      operator: "or",
      value: [
        {
          operator: "and",
          value: [
            {
              field: "name",
              operator: "eq",
              value: "John Doe",
            },
            {
              field: "age",
              operator: "eq",
              value: 30,
            },
          ],
        },
        {
          operator: "and",
          value: [
            {
              field: "name",
              operator: "eq",
              value: "JR Doe",
            },
            {
              field: "age",
              operator: "eq",
              value: 1,
            },
          ],
        },
      ],
    }

3.84.0

Minor Changes

  • Marked getMany, createMany, updateMany and deleteMany functions as optional and substituted with getOne, create, update and deleteOne respectively. Now users can choose to skip implementing getMany, createMany, updateMany and deleteMany functions and use getOne, create, update and deleteOne functions instead.

    Breaking Change

    • getMany, createMany, updateMany and deleteMany functions are now optional and may cause type issues if used outside of the refine hooks.

3.83.0

Minor Changes

  • #2688 508045ac30 Thanks @aliemir! - Marked getMany, createMany, updateMany and deleteMany functions as optional and substituted with getOne, create, update and deleteOne respectively. Now users can choose to skip implementing getMany, createMany, updateMany and deleteMany functions and use getOne, create, update and deleteOne functions instead.

    Breaking Change

    • getMany, createMany, updateMany and deleteMany functions are now optional and may cause type issues if used outside of the refine hooks.

3.82.0

Minor Changes

  • Added useSelect(), setState handler functions are memoized

    Fixed when queryOptions.enabled = true on useSelect(), fetches all data. #2691

Patch Changes

  • fix: useSelect()'s overridden onSearch function is not calling when value is empty.

3.81.0

Minor Changes

  • #2704 e4d78052ef Thanks @alicanerdurmaz! - Added useSelect(), setState handler functions are memoized

    Fixed when queryOptions.enabled = true on useSelect(), fetches all data. #2691

Patch Changes

3.80.0

Minor Changes

  • Added infinite loading example to antd useSelect() useSelect() fetchSize prop is deprecated. From now pagination should be used

  • Added dataProviderName property to resource options. Now you can define default data provider per resource.

    Usage

    <Refine
      dataProvider={{
        default: myProvider,
        second: mySecondProvider,
      }}
      resources={[
        {
          name: "posts",
          options: {
            dataProviderName: "second",
          },
        },
      ]}
    />

Patch Changes

  • Add AuthProps type export

  • Mark default key as required for multiple data providers in dataProvider prop of <Refine /> component.

3.79.0

Minor Changes

  • #2629 bc89228e73 Thanks @bungambohlah! - Added infinite loading example to antd useSelect() useSelect() fetchSize prop is deprecated. From now pagination should be used

  • #2674 3bd6196056 Thanks @aliemir! - Added dataProviderName property to resource options. Now you can define default data provider per resource.

    Usage

    <Refine
      dataProvider={{
        default: myProvider,
        second: mySecondProvider,
      }}
      resources={[
        {
          name: "posts",
          options: {
            dataProviderName: "second",
          },
        },
      ]}
    />

Patch Changes

3.78.0

Minor Changes

  • clientConfig property now accepts QueryClient instance - #2665

    Usage

    import { QueryClient } from "@tanstack/react-query";
    const queryClient = new QueryClient();
    const App: React.FC = () => (
        <Refine
            ...
            options={{
                reactQuery: {
                    clientConfig: queryClient
                },
            }}
        />
    );

3.77.0

Minor Changes

  • #2670 f260932051 Thanks @alicanerdurmaz! - clientConfig property now accepts QueryClient instance - #2665

    Usage

    import { QueryClient } from "@tanstack/react-query";
    const queryClient = new QueryClient();
    const App: React.FC = () => (
        <Refine
            ...
            options={{
                reactQuery: {
                    clientConfig: queryClient
                },
            }}
        />
    );

3.76.0

Minor Changes

    • Added new <AuthPage /> component core and mantine support.
    • Move Auth types @pankod/refine-ui-types to @pankod/refine-core

Patch Changes

  • fix core data hooks type errors

3.75.1

Patch Changes

3.75.0

Minor Changes

  • #2627 c5fb45d61f Thanks @yildirayunlu! - - Added new <AuthPage /> component core and mantine support.
    • Move Auth types @pankod/refine-ui-types to @pankod/refine-core

3.74.8

Patch Changes

  • add props table to useCan documentation

3.74.7

Patch Changes

3.74.6

Patch Changes

  • Updated devtoolConfig type.

3.74.5

Patch Changes

3.74.4

Patch Changes

  • Fixed useMenu hook is not reacting to locale change - #2598

3.74.3

Patch Changes

3.74.2

Patch Changes

  • Removed redundant type inheritance

3.74.1

Patch Changes

3.74.0

Minor Changes

  • Combine action related types into a single file and derive types from it to avoid future inconsistencies.

    Renamed RedirectionTypes type to RedirectAction.

    Updated every type definition of actions to use the new Action type or derivations of it.

Patch Changes

  • Fixed the issue in resource routes not taking options.route of parent resource into account.

  • Rename reset-password -> forgot-password on docs.

3.73.0

Minor Changes

  • Combine action related types into a single file and derive types from it to avoid future inconsistencies.

    Renamed RedirectionTypes type to RedirectAction.

    Updated every type definition of actions to use the new Action type or derivations of it.

Patch Changes

  • Fixed the issue in resource routes not taking options.route of parent resource into account.

  • Rename reset-password -> forgot-password on docs.

3.72.1

Patch Changes

3.72.0

Minor Changes

  • #2486 ee4d0d112a Thanks @aliemir! - Combine action related types into a single file and derive types from it to avoid future inconsistencies.

    Renamed RedirectionTypes type to RedirectAction.

    Updated every type definition of actions to use the new Action type or derivations of it.

Patch Changes

  • #2486 ee4d0d112a Thanks @aliemir! - Fixed the issue in resource routes not taking options.route of parent resource into account.

3.71.2

Patch Changes

  • Fix useImport hook requests with properly invoking requests sequentially and manage progress state.

  • Removed children property from useCans params.resource since it can be in ITreeMenu type and React.ReactNode breaks the react-querys key stringify function.

  • Fixed undoable mutation is called many times - #2556

3.71.1

Patch Changes

  • #2560 373cee23ba Thanks @aliemir! - Fix useImport hook requests with properly invoking requests sequentially and manage progress state.

  • #2537 4407bf8825 Thanks @ozkalai! - Removed children property from useCans params.resource since it can be in ITreeMenu type and React.ReactNode breaks the react-querys key stringify function.

  • #2559 75b699cd6c Thanks @omeraplak! - Fixed undoable mutation is called many times - #2556

3.71.0

Minor Changes

    • Renamed resetPassword in AuthProvider to forgotPassword
    • Renamed useResetPassword hook to useForgotPassword

3.70.0

Minor Changes

  • #2524 27bf81bebb Thanks @biskuvit! - - Renamed resetPassword in AuthProvider to forgotPassword
    • Renamed useResetPassword hook to useForgotPassword

3.69.9

Patch Changes

  • Add register function to AuthContextProvider for invalidate auth store queries.

  • Fixed version of react-router to 6.3.0

3.69.8

Patch Changes

3.69.7

Patch Changes

3.69.6

Patch Changes

  • Fix import of react-query DevtoolsOptions interface

3.69.5

Patch Changes

3.69.4

Patch Changes

  • Fixed default login page for headless

3.69.3

Patch Changes

3.69.2

Patch Changes

  • Update useForm and useShow hooks to watch for id from props and update the query with the new id when it changes.

3.69.1

Patch Changes

  • #2467 21bb649bc7 Thanks @aliemir! - Update useForm and useShow hooks to watch for id from props and update the query with the new id when it changes.

3.69.0

Minor Changes

  • Adding more CRUD Filter Operators

  • Add initialData support to DashboardPage for @pankod/refine-nextjs-router.

3.68.0

Minor Changes

3.67.0

Minor Changes

  • Updated the generation of type declarations, moved the declarations from tsup to tsc for a better experience with Peek Definition and Go to Definition features. After this change, it's expected to navigate to the source code of the refine packages instead of the dist directory with combined declarations.

  • Removed jose dependency.

  • Remove decamelize dependency from humanizeString helper and replace the functionality with regExp.

Patch Changes

  • Fixed the issue with the TS compiler and useResource hooks return type.

  • Pass dataProviderName prop to mutations in @pankod/refine-core's useImport hook.

3.66.1

Patch Changes

  • #2448 f1edb19979 Thanks @aliemir! - Pass dataProviderName prop to mutations in @pankod/refine-core's useImport hook.

3.66.0

Minor Changes

  • #2440 0150dcd070 Thanks @aliemir! - Updated the generation of type declarations, moved the declarations from tsup to tsc for a better experience with Peek Definition and Go to Definition features. After this change, it's expected to navigate to the source code of the refine packages instead of the dist directory with combined declarations.

  • #2439 f2faf99f25 Thanks @yildirayunlu! - Removed jose dependency.

  • #2443 2c428b3105 Thanks @ozkalai! - Remove decamelize dependency from humanizeString helper and replace the functionality with regExp.

Patch Changes

3.65.3

Patch Changes

  • Fixed, loginLink and registerLink texts and remove unnecessary props from forms

  • Fixed syncWithLocation not tracking when useTable filters were reset

3.65.2

Patch Changes

3.65.1

Patch Changes

3.65.0

Minor Changes

  • 🎉 Added AuthPage component to the refine app. This page is used to login, register, forgot password and update password. Login page is default page and old LoginPage component is deprecated.

    New Auth Hooks

    📌 Added useRegister hook. This hook is used to register new user. useRegister falls into register function of AuthProvider.

    📌 Added useForgotPassword hook. This hook is used to forgot password. useForgotPassword falls into forgotPassword function of AuthProvider.

    📌 Added useUpdatePassword hook. This hook is used to update password. useUpdatePassword falls into updatePassword function of AuthProvider.

    - <LoginPage>
    + <AuthPage>

    New AuthPage props:

    interface IAuthPageProps extends IAuthCommonProps {
        type?: "login" | "register" | "forgotPassword" | "updatePassword";
    }
    
    interface IAuthCommonProps {
        submitButton?: React.ReactNode;
        registerLink?: React.ReactNode;
        loginLink?: React.ReactNode;
        forgotPasswordLink?: React.ReactNode;
        updatePasswordLink?: React.ReactNode;
        backLink?: React.ReactNode;
        providers?: IProvider[];
    }
    
    interface IProvider {
        name: string;
        icon?: React.ReactNode;
        label?: string;
    }

Patch Changes

  • Fixed <AuthPage> by adding missing props to "login" and "register" pages.

    Fixed <Refine> component LoginPage property.

3.64.2

Patch Changes

  • #2415 f7c98f0ef9 Thanks @biskuvit! - Fixed <AuthPage> by adding missing props to "login" and "register" pages.

    Fixed <Refine> component LoginPage property.

3.64.1

Patch Changes

  • #2299 a02cb9e8ef Thanks @biskuvit! - 🎉 Added AuthPage to the refine app. This page is used to login, register, forgot password and update password. Login page is default page and old LoginPage component is deprecated.

    New Auth Hooks

    📌 Added useRegister hook. This hook is used to register new user. useRegister falls into register function of AuthProvider.

    📌 Added useForgotPassword hook. This hook is used to forgot password. useForgotPassword falls into forgotPassword function of AuthProvider.

    📌 Added useUpdatePassword hook. This hook is used to update password. useUpdatePassword falls into updatePassword function of AuthProvider.

    - <LoginPage>
    + <AuthPage>

    New AuthPage props:

    interface IAuthPageProps extends IAuthCommonProps {
        type?: "login" | "register" | "forgotPassword" | "updatePassword";
    }
    
    interface IAuthCommonProps {
        registerLink?: React.ReactNode;
        loginLink?: React.ReactNode;
        forgotPasswordLink?: React.ReactNode;
        updatePasswordLink?: React.ReactNode;
        backLink?: React.ReactNode;
        providers?: IProvider[];
    }
    
    interface IProvider {
        name: string;
        icon?: React.ReactNode;
        label?: string;
    }

    Add AuthPage as a default page to Routers

    📌 Added AuthPage to the refine-nextjs-router. Default page is AuthPage.

    📌 Added AuthPage to the refine-react-location. Default page is AuthPage.

    📌 Added AuthPage to the refine-react-router-v6. Default page is AuthPage.

    📌 Added AuthPage to the refine-remix-router. Default page is AuthPage.

3.64.0

Minor Changes

  • Add an option to hide resources from the Sider menu

    <Refine
        ...
        ...
        resources={[
            {
                name: "posts",
                list: PostList,
                options: {
                    hide: true,
                },
            },
        ]}
    />
  • Add object path syntax support for the useSelect hook

    useSelect({
      resource: "posts",
      optionLabel: "nested.title",
      optionLabel: "nested.id",
    });

3.63.0

Minor Changes

  • #2391 e530670c2d Thanks @omeraplak! - Add an option to hide resources from the Sider menu

    <Refine
        ...
        ...
        resources={[
            {
                name: "posts",
                list: PostList,
                options: {
                    hide: true,
                },
            },
        ]}
    />
  • #2395 3019fae7a0 Thanks @omeraplak! - Add object path syntax support for the useSelect hook

    useSelect({
      resource: "posts",
      optionLabel: "nested.title",
      optionLabel: "nested.id",
    });

3.62.1

Patch Changes

  • fix redirectPage return value #2377

3.62.0

Minor Changes

  • Added a new <Refine> component property: options.

    Previously, the options were passed as a property to the <Refine> component. Now, the options are passed to the <Refine> via options property like this:

        <Refine
    -       mutationMode="undoable"
    -       undoableTimeout={5000}
    -       warnWhenUnsavedChanges
    -       syncWithLocation
    -       liveMode="off"
    -       disableTelemetry={false}
    +       options={{
    +           mutationMode: "undoable",
    +           undoableTimeout: 5000,
    +           warnWhenUnsavedChanges: true,
    +           syncWithLocation: true,
    +           liveMode: "off",
    +           disableTelemetry: false,
    +       }}
        />
  • Added a new redirect feature. It is now possible to set default redirects.

    By default, when a form is submitted, it will redirect to the "list" page of the current resource. You can change this behavior by setting the redirect parameter like this:

    <Refine
        ...
        options={{ redirect: { afterCreate: "show", afterClone: "edit", afterEdit: false }, }}
    />

Patch Changes

    • lodash moved to "dependencies" for CommonJS builds
    • Fixed lodash-es usage for ESM builds

3.61.1

Patch Changes

3.61.0

Minor Changes

  • Added a new <Refine> component property: options.

    Previously, the options were passed as a property to the <Refine> component. Now, the options are passed to the <Refine> via options property like this:

        <Refine
    -       mutationMode="undoable"
    -       undoableTimeout={5000}
    -       warnWhenUnsavedChanges
    -       syncWithLocation
    -       liveMode="off"
    -       disableTelemetry={false}
    +       options={{
    +           mutationMode: "undoable",
    +           undoableTimeout: 5000,
    +           warnWhenUnsavedChanges: true,
    +           syncWithLocation: true,
    +           liveMode: "off",
    +           disableTelemetry: false,
    +       }}
        />
  • Added a new redirect feature. It is now possible to set default redirects.

    By default, when a form is submitted, it will redirect to the "list" page of the current resource. You can change this behavior by setting the redirect parameter like this:

    <Refine
        ...
        options={{ redirect: { afterCreate: "show", afterClone: "edit", afterEdit: false }, }}
    />

Patch Changes

    • lodash moved to "dependencies" for CommonJS builds
    • Fixed lodash-es usage for ESM builds

3.60.0

Minor Changes

  • Added a new <Refine> component property: options.

    Previously, the options were passed as a property to the <Refine> component. Now, the options are passed to the <Refine> via options property like this:

        <Refine
    -       mutationMode="undoable"
    -       undoableTimeout={5000}
    -       warnWhenUnsavedChanges
    -       syncWithLocation
    -       liveMode="off"
    -       disableTelemetry={false}
    +       options={{
    +           mutationMode: "undoable",
    +           undoableTimeout: 5000,
    +           warnWhenUnsavedChanges: true,
    +           syncWithLocation: true,
    +           liveMode: "off",
    +           disableTelemetry: false,
    +       }}
        />
  • Added a new redirect feature. It is now possible to set default redirects.

    By default, when a form is submitted, it will redirect to the "list" page of the current resource. You can change this behavior by setting the redirect parameter like this:

    <Refine
        ...
        options={{ redirect: { afterCreate: "show", afterClone: "edit", afterEdit: false }, }}
    />

Patch Changes

    • lodash moved to "dependencies" for CommonJS builds
    • Fixed lodash-es usage for ESM builds

3.59.0

Minor Changes

  • #2352 e4d39eff33 Thanks @salihozdemir! - Added a new <Refine> component property: options.

    Previously, the options were passed as a property to the <Refine> component. Now, the options are passed to the <Refine> via options property like this:

        <Refine
    -       mutationMode="undoable"
    -       undoableTimeout={5000}
    -       warnWhenUnsavedChanges
    -       syncWithLocation
    -       liveMode="off"
    -       disableTelemetry={false}
    +       options={{
    +           mutationMode: "undoable",
    +           undoableTimeout: 5000,
    +           warnWhenUnsavedChanges: true,
    +           syncWithLocation: true,
    +           liveMode: "off",
    +           disableTelemetry: false,
    +       }}
        />
  • #2361 95e1a17cd1 Thanks @salihozdemir! - Added a new redirect feature. It is now possible to set default redirects.

    By default, when a form is submitted, it will redirect to the "list" page of the current resource. You can change this behavior by setting the redirect parameter like this:

    <Refine
        ...
        options={{ redirect: { afterCreate: "show", afterClone: "edit", afterEdit: false }, }}
    />

Patch Changes

3.58.5

Patch Changes

  • lodash moved to dependencies.

3.58.4

Patch Changes

3.58.3

Patch Changes

  • Fixed react-query devtools was consuming high CPU

3.58.2

Patch Changes

3.58.1

Patch Changes

  • AuthProvider's login method can now return a value for Remix's authentication flow

3.58.0

Minor Changes

  • Updated reactQueryDevtoolConfig prop type and added false option to disable the React Query Devtools.

3.57.0

Minor Changes

  • #2311 645391a3d9 Thanks @aliemir! - Updated reactQueryDevtoolConfig prop type and added false option to disable the React Query Devtools.

3.56.11

Patch Changes

  • Fixed user-defined URL query parameters being deleted when using syncWithLocation

3.56.10

Patch Changes

3.56.9

Patch Changes

3.56.8

Patch Changes

  • Fixed @tanstack/react-query-devtools dependency

3.56.7

Patch Changes

3.56.6

Patch Changes

  • Upgraded react-query version to 4.

  • Updated the return value of useGetIdentity. When the getUserIdentity function is not defined, it returns {} instead of undefined.

3.56.5

Patch Changes

3.56.4

Patch Changes

  • Fix useCan hook params keys.

    Since react-query stringifies the query keys, it will throw an error for a circular dependency if we include React.ReactNode elements inside the keys. The feature in #2220(https://github.com/refinedev/refine/issues/2220) includes such change and to fix this, we need to remove icon property in the resource

  • Updated <Refine/> component with memoization to prevent unwanted effects.

    • Fixed the issue: react-query's queryClient was re-initializing on every render which was causing it to reset the query cache.
    • Memoized the notificationProvider prop to prevent unnecessary re-renders.
    • Memoized the resources prop to prevent unnecessary transform calls on every render.
    • Fixed Browser back navigation is broken with syncWithLocation and paginated useTable - #2276
    • Updated push and replace args of useNavigation

3.56.3

Patch Changes

  • #2278 8b11f8a267 Thanks @biskuvit! - Fix useCan hook params keys.

    Since react-query stringifies the query keys, it will throw an error for a circular dependency if we include React.ReactNode elements inside the keys. The feature in #2220(https://github.com/refinedev/refine/issues/2220) includes such change and to fix this, we need to remove icon property in the resource

  • #2280 e22cac6d8b Thanks @aliemir! - Updated <Refine/> component with memoization to prevent unwanted effects.

    • Fixed the issue: react-query's queryClient was re-initializing on every render which was causing it to reset the query cache.
    • Memoized the notificationProvider prop to prevent unnecessary re-renders.
    • Memoized the resources prop to prevent unnecessary transform calls on every render.
  • #2279 786fb08b8b Thanks @omeraplak! - - Fixed Browser back navigation is broken with syncWithLocation and paginated useTable - #2276

    • Updated push and replace args of useNavigation

3.56.2

Patch Changes

  • Fixed invalidation of authentication caches every time checkAuth is run

3.56.1

Patch Changes

3.56.0

Minor Changes

  • Add React@18 support 🚀

3.55.0

Minor Changes

3.54.0

Minor Changes

  • Added config parameter to useCustomMutationHook to send headers.

    const apiUrl = useApiUrl();
    
    const { mutate } = useCustomMutation<ICategory>();
    
    mutate({
        url: `${API_URL}/categories`,
        method: "post",
        values: {
          title: "New Category",
        },
        config: {
          headers: {
              Authorization: "Bearer ****",
          },
        },
    });

3.53.0

Minor Changes

  • #2245 e949df7f1c Thanks @yildirayunlu! - Added config parameter to useCustomMutationHook to send headers.

    const apiUrl = useApiUrl();
    
    const { mutate } = useCustomMutation<ICategory>();
    
    mutate({
        url: `${API_URL}/categories`,
        method: "post",
        values: {
          title: "New Category",
        },
        config: {
          headers: {
              Authorization: "Bearer ****",
          },
        },
    });

3.52.0

Minor Changes

  • Added useCustomMutationhook for custom mutation requests.

    import { useCustomMutation } from "@pankod/refine-core";
    const { mutation } = useCustomMutation();
    
    mutation({
      url: "https://api.example.com/users",
      method: "POST",
      values: {
        name: "John Doe",
        email: "johndoe@mail.com",
      },
    });

3.51.0

Minor Changes

  • #2229 878e9a105e Thanks @yildirayunlu! - Added useCustomMutationhook for custom mutation requests.

    import { useCustomMutation } from "@pankod/refine-core";
    const { mutation } = useCustomMutation();
    
    mutation({
      url: "https://api.example.com/users",
      method: "POST",
      values: {
        name: "John Doe",
        email: "johndoe@mail.com",
      },
    });

3.50.0

Minor Changes

  • Pass the full resource to the accessControlProvider can method. This will enable Attribute Based Access Control (ABAC), for example granting permissions based on the value of a field in the resource object.

    const App: React.FC = () => {
      <Refine
        // other providers and props
        accessControlProvider={{
          can: async ({ resource, action, params }) => {
            if (resource === "posts" && action === "edit") {
              return Promise.resolve({
                can: false,
                reason: "Unauthorized",
              });
            }
    
            // or you can access directly *resource object
            // const resourceName = params?.resource?.name;
            // const anyUsefulOption = params?.resource?.options?.yourUsefulOption;
            // if (resourceName === "posts" && anyUsefulOption === true && action === "edit") {
            //     return Promise.resolve({
            //         can: false,
            //         reason: "Unauthorized",
            //     });
            // }
    
            return Promise.resolve({ can: true });
          },
        }}
      />;
    };

3.49.0

Minor Changes

  • #2222 43e92b9785 Thanks @omeraplak! - Pass the full resource to the accessControlProvider can method. This will enable Attribute Based Access Control (ABAC), for example granting permissions based on the value of a field in the resource object.

    const App: React.FC = () => {
      <Refine
        // other providers and props
        accessControlProvider={{
          can: async ({ resource, action, params }) => {
            if (resource === "posts" && action === "edit") {
              return Promise.resolve({
                can: false,
                reason: "Unauthorized",
              });
            }
    
            // or you can access directly *resource object
            // const resourceName = params?.resource?.name;
            // const anyUsefulOption = params?.resource?.options?.yourUsefulOption;
            // if (resourceName === "posts" && anyUsefulOption === true && action === "edit") {
            //     return Promise.resolve({
            //         can: false,
            //         reason: "Unauthorized",
            //     });
            // }
    
            return Promise.resolve({ can: true });
          },
        }}
      />;
    };

3.48.0

Minor Changes

  • All of the refine packages have dependencies on the @pankod/refine-core package. So far we have managed these dependencies with peerDependencies + dependencies but this causes issues like #2183. (having more than one @pankod/refine-core version in node_modules and creating different instances)

    Managing as peerDependencies + devDependencies seems like the best way for now to avoid such issues.

Patch Changes

  • Fix adding the current path to the to parameter when redirecting to the login page after logout - #2211

3.47.0

Minor Changes

  • #2217 b4aae00f77 Thanks @omeraplak! - All of the refine packages have dependencies on the @pankod/refine-core package. So far we have managed these dependencies with peerDependencies + dependencies but this causes issues like #2183. (having more than one @pankod/refine-core version in node_modules and creating different instances)

    Managing as peerDependencies + devDependencies seems like the best way for now to avoid such issues.

3.46.0

Minor Changes

  • Update notification props in data hooks of @pankod/refine-core to cover dynamic notifications.

    Now users will be able to show notifications according to the API response by assigning a function which returns OpenNotificationParams instead of an OpenNotificationParams object.

    Example

    {
        const { mutate } = useCreate({
            /* ... */
            successNotification: (data, values, resource) => ({
                message: data?.message ?? "Success!",
                type: "success",
                description: data?.description;
            }),
            errorNotification: (error, values, resource) => ({
                message: error?.message ?? error?.code ?? "Error!",
                type: "error",
                description: error?.reason;
            })
            /* ... */
        });
    }

3.45.0

Minor Changes

  • #2177 5a805c789a Thanks @aliemir! - Update notification props in data hooks of @pankod/refine-core to cover dynamic notifications.

    Now users will be able to show notifications according to the API response by assigning a function which returns OpenNotificationParams instead of an OpenNotificationParams object.

    Example

    {
        const { mutate } = useCreate({
            /* ... */
            successNotification: (data, values, resource) => ({
                message: data?.message ?? "Success!",
                type: "success",
                description: data?.description;
            }),
            errorNotification: (error, values, resource) => ({
                message: error?.message ?? error?.code ?? "Error!",
                type: "error",
                description: error?.reason;
            })
            /* ... */
        });
    }

3.44.0

Minor Changes

  • Added ability to compare or filters. This was a missing feature on filters in useTable hook. With this feature, we will prevent or filter bugs (Resolves #2124) such as re-adding the same filters and being unable to modify or filter. To remove or filter with merge behavior, you should pass an empty object as value.

Patch Changes

  • Fix redirection after submit in useForm. Both edit and create will redirect to list (it was edit previously)

    Resolves #2123

3.43.1

Patch Changes

  • #2172 c33d13eb15 Thanks @aliemir! - Fix redirection after submit in useForm. Both edit and create will redirect to list (it was edit previously)

    Resolves #2123

3.43.0

Minor Changes

  • #2164 4d5f6b25e5 Thanks @aliemir! - Added ability to compare or filters. This was a missing feature on filters in useTable hook. With this feature, we will prevent or filter bugs (Resolves #2124) such as re-adding the same filters and being unable to modify or filter. To remove or filter with merge behavior, you should pass an empty object as value.

3.42.0

Minor Changes

  • @pankod/refine-core

    • Added extra params to useSubscription and useResourceSubscription
    • useOne, useMany and useList passed extra params to own subscription hook.

    @pankod/refine-hasura

    • Added liveProvider.

    To see an example of how to use it, check out here.

    @pankod/refine-nhost

    • Added liveProvider.

    To see an example of how to use it, check out here.

    @pankod/refine-graphql

    • Added liveProvider.

Patch Changes

  • Fixed it to appear in menu items even if List is not given in resources #2147

3.41.1

Patch Changes

3.41.0

Minor Changes

  • #2120 2aa7aace52 Thanks @salihozdemir! - ### @pankod/refine-core

    • Added extra params to useSubscription and useResourceSubscription
    • useOne, useMany and useList passed extra params to own subscription hook.

    @pankod/refine-hasura

    • Added liveProvider.

    To see an example of how to use it, check out here.

    @pankod/refine-nhost

    • Added liveProvider.

    To see an example of how to use it, check out here.

    @pankod/refine-graphql

    • Added liveProvider.

3.40.0

Minor Changes

  • Add a simple and transparent telemetry module to collect usage statistics defined within a very limited scope.

    Tracking is completely safe and anonymous. It does not contain any personally identifiable information and does not use cookies. Participation is optional and users can opt out easily.

    For more information, you can check the documentation.

3.39.0

Minor Changes

  • #2078 868bb943ad Thanks @yildirayunlu! - Add a simple and transparent telemetry module to collect usage statistics defined within a very limited scope.

    Tracking is completely safe and anonymous. It does not contain any personally identifiable information and does not use cookies. Participation is optional and users can opt out easily.

    For more information, you can check the documentation.

3.38.2

Patch Changes

    • The redirect method that return from useForm updated to be avaiable for passing id.
    const { redirect } = useForm();
    
    redirect("edit", id);
    • Returning API response to onFinish function for successful mutations

3.38.1

Patch Changes

  • #2089 ee8e8bbd6c Thanks @ozkalai! - - The redirect method that return from useForm updated to be avaiable for passing id.

    const { redirect } = useForm();
    
    redirect("edit", id);
    • Returning API response to onFinish function for successful mutations

3.38.0

Minor Changes

  • useLog is converted to useQuery mutation.

    // before
    const { log } = useLog();
    log({
      resource: 'posts',
      action: 'create',
      data: {
          id: 1
      }
    });
    // after
    const { log } = useLog();
    const { mutation } = log;
    mutation({
      resource: 'posts',
      action: 'create',
      data: {
          id: 1
      }
    });

Patch Changes

  • Fixed useBreadcrumb hook throws console.warn even if i18nProvider is not used - #2103

3.37.0

Minor Changes

  • #2049 98966b586f Thanks @yildirayunlu! - useLog is converted to useQuery mutation.

    // before
    const { log } = useLog();
    log({
      resource: 'posts',
      action: 'create',
      data: {
          id: 1
      }
    });
    // after
    const { log } = useLog();
    const { mutation } = log;
    mutation({
      resource: 'posts',
      action: 'create',
      data: {
          id: 1
      }
    });

Patch Changes

  • #2104 9d77c63a92 Thanks @omeraplak! - Fixed useBreadcrumb hook throws console.warn even if i18nProvider is not used - #2103

3.36.0

Minor Changes

  • Ability to disable server-side pagination on useTable and useList hooks.

    Implementation

    Added hasPagination property to useTable to enable/disable pagination. Updated useList config with no pagination option. Set hasPagination to false to disable pagination. useTable hook uses the useList hook under the hood and propagates the hasPagination property to it. Also setting pagination related return values to undefined for better type check on the user side.

    Use Cases

    In some data providers, some of the resources might not support pagination which was not supported prior to these changes. To handle the pagination on the client-side or to disable completely, users can set hasPagination to false.

Patch Changes

  • Added actions translate support for CRUD operations (list,create,edit,show) in the useBreadcrumb useBreadcrumb hook.

    ️⃣ First, We need to add the actions key to the translation file.

        "actions": {
            "list": "List",
            "create": "Create",
            "edit": "Edit",
            "show": "Show"
        },

    ️⃣ If you don't provide the actions key, useBreadcrumb will try to find the buttons key in the translation file for backward compatibility.

        "buttons": {
            "list": "List",
            "create": "Create",
            "edit": "Edit",
            "show": "Show"
        },

    🎉 You can check the code part of this pull request to see how it works here👇🏼

    const key = `actions.${action}`;
    const actionLabel = translate(key);
    if (actionLabel === key) {
      console.warn(
        `Breadcrumb missing translate key for the "${action}" action. Please add "actions.${action}" key to your translation file. For more information, see https://refine.dev/docs/core/hooks/useBreadcrumb/#i18n-support`,
      );
      breadcrumbs.push({
        label: translate(`buttons.${action}`, humanizeString(action)),
      });
    } else {
      breadcrumbs.push({
        label: translate(key, humanizeString(action)),
      });
    }

3.35.0

Minor Changes

  • #2050 635cfe9fdb Thanks @ozkalai! - Ability to disable server-side pagination on useTable and useList hooks.

    Implementation

    Added hasPagination property to useTable to enable/disable pagination. Updated useList config with no pagination option. Set hasPagination to false to disable pagination. useTable hook uses the useList hook under the hood and propagates the hasPagination property to it. Also setting pagination related return values to undefined for better type check on the user side.

    Use Cases

    In some data providers, some of the resources might not support pagination which was not supported prior to these changes. To handle the pagination on the client-side or to disable completely, users can set hasPagination to false.

Patch Changes

  • #2069 ecde34a9b3 Thanks @biskuvit! - Added actions translate support for CRUD operations (list,create,edit,show) in the useBreadcrumb useBreadcrumb hook.

    ️⃣ First, We need to add the actions key to the translation file.

        "actions": {
            "list": "List",
            "create": "Create",
            "edit": "Edit",
            "show": "Show"
        },

    ️⃣ If you don't provide the actions key, useBreadcrumb will try to find the buttons key in the translation file for backward compatibility.

        "buttons": {
            "list": "List",
            "create": "Create",
            "edit": "Edit",
            "show": "Show"
        },

    🎉 You can check the code part of this pull request to see how it works here👇🏼

    const key = `actions.${action}`;
    const actionLabel = translate(key);
    if (actionLabel === key) {
      console.warn(
        `Breadcrumb missing translate key for the "${action}" action. Please add "actions.${action}" key to your translation file. For more information, see https://refine.dev/docs/core/hooks/useBreadcrumb/#i18n-support`,
      );
      breadcrumbs.push({
        label: translate(`buttons.${action}`, humanizeString(action)),
      });
    } else {
      breadcrumbs.push({
        label: translate(key, humanizeString(action)),
      });
    }

3.34.2

Patch Changes

  • Fixed useImport onFinish twice call bug.

3.34.1

Patch Changes

3.34.0

Minor Changes

  • Added i18n support for resource names on useBreadcrumb hook.

  • Export RefineProps and ResourceProps type.

Patch Changes

  • We have fixed texts with translations of default login pages in Material UI and Headless.

3.33.0

Minor Changes

Patch Changes

  • #2029 b257d87fef Thanks @ozkalai! - We have fixed texts with translations of default login pages in Material UI and Headless.

3.32.0

Minor Changes

  • Add useMenu hook to @pankod/refine-core

Patch Changes

  • Add custom route support to defaultOpenKeys in useMenu

  • Handle the undefined case at audit-log logger in data hooks.

  • Remove dashboard item in useMenu hook

3.31.0

Minor Changes

Patch Changes

3.30.0

Minor Changes

  • Add useMenu hook to @pankod/refine-core

Patch Changes

  • Add custom route support to defaultOpenKeys in useMenu

  • Handle the undefined case at audit-log logger in data hooks.

3.29.2

Patch Changes

  • Fix hook-inside-hook call in notificationProvider setup at <Refine/>

3.29.1

Patch Changes

3.29.0

Minor Changes

  • Updated notificationProvider prop in the Refine wrapper component to be able to lazily initialized.

3.28.0

Minor Changes

  • Updated notificationProvider prop in the Refine wrapper component to be able to lazily initialized.

3.27.0

Minor Changes

  • Updated notificationProvider prop in the Refine wrapper component to be able to lazily initialized.

3.26.0

Minor Changes

  • #1896 2ba2a96fd2 Thanks @aliemir! - Updated notificationProvider prop in the Refine wrapper component to be able to lazily initialized.

3.23.2

Patch Changes

  • #1873 2deb19babf Thanks @aliemir! - Removed dummy default values from internal contexts. Updated contexts:

    • Auth
    • Access Control
    • Notification
    • Translation (i18n)
    • unsavedWarn

    BREAKING: useGetLocale hook now can return undefined instead of a fallback value of en in cases of i18nProvider being undefined.

3.23.1

Patch Changes

3.23.0

Minor Changes