Skip to main content
Refine AI
Version: 4.xx.xx

Notifications

One of the most important parts of an application is the notifications and the visual feedbacks. Refine has this built-in notification integration that works automatically when it's needed in cases such as when a request fails or when a form is submitted.

While this integration is not coupled with the UI integrations, it will be a wise choice to use the one that is provided by the UI libraries for a consistent design language. This is why Refine's UI integrations also provides a notificationProvider to be used with the notification integration of refine.

Notification Providers

Refine let's you set a notification API by providing the notificationProvider property to the <Refine /> component. notificationProvider is an object with close and open methods. Refine uses these methods to show and hide notifications. These methods can be called from anywhere in the application with useNotification hook.

An notificationProvider must include open and close methods with the following types:

interface NotificationProvider {
open: (params: OpenNotificationParams) => void;
close: (key: string) => void;
}

interface OpenNotificationParams {
key?: string;
message: string;
type: "success" | "error" | "progress";
description?: string;
cancelMutation?: () => void;
undoableTimeout?: number;
}

Once you provide the notification provider, Refine seamlessly integrate with data hooks to displays user-friendly notifications for various data-related actions, ensuring a clear and informative user experience. This includes:

  • Form Submission: Whether a form is successfully submitted or encounters errors, Refine will display the appropriate notification to keep the user informed.
  • Resource Management: Creation, deletion, update, import, and export of resources are all accompanied by success or error notifications, providing immediate feedback to the user.
  • Data Fetching: Refine also displays notifications for failed data fetching operations, including those using useList, useInfiniteList, useMany, useOne.
  • Auth Actions: Login, logout, register, update password, and forgot password actions are all integrated with Refine's notification provider to display error notifications.

Built-in Notification Providers

Using of the prebuilt notification providers are optional and can be customized, extended or even swapped with a custom implementation if needed.

As an example, we'll demonstrate how to open and close notifications using the useNotification hook. However, in most cases, you won't need to do this, as Refine typically manages notifications for you automatically.

import React from "react";
import { useNotification } from "@refinedev/core";
import { Button, Col, Row } from "antd";

export const HomePage: React.FC = () => {
  const { open, close } = useNotification();

  return (
      <Row
          gutter={[16, 16]}
          style={{
              justifyContent: "center",
              alignItems: "center",
              height: "100vh",
          }}
      >
          <Col>
              <Button
                  type="primary"
                  onClick={() => {
                      open?.({
                          type: "success",
                          message: "Notification Title",
                          description:
                              "This is the content of the notification.",
                          key: "notification-key",
                      });
                  }}
              >
                  Open Notification
              </Button>
          </Col>
          <Col>
              <Button
                  type="default"
                  onClick={() => {
                      close?.("notification-key");
                  }}
              >
                  Close Notification
              </Button>
          </Col>
      </Row>
  );
};

Undoable

Refine also supports undoable notification.

You can trigger an undoable notification by setting the type to progress. After timeout, the notification will be closed automatically. If the user clicks the undo button, the cancelMutation callback will be called.

const { open } = useNotification();

open?.({
type: "progress",
message: "Progress",
undoableTimeout: 5,
cancelMutation: () => {
// when undo button is clicked, run this callback
},
});

Mutation hooks such as useUpdate, useDelete and useForm supports undoable notifications. It can be used for canceling the mutation.

import { useForm } from "@refinedev/core";

// automatically cancel the mutation when undo button is clicked
useForm({ mutationMode: "undoable" });

Customizing Notifications

With props

All data hooks have a successNotification and errorNotification prop that can be used to customize the notification that will be shown when the hook is called.

We will look useUpdate and useForm hooks as an example but all data hooks have the same props and they work the same way.

import { useUpdate } from "@refinedev/core";

const { mutate } = useUpdate();

mutate({
// it will be called when the mutation is successful
// By setting it to `false`, you can disable the notification.
successNotification: (data, values, resource) => {
return {
message: `${data.title} Successfully fetched.`,
description: "Success with no errors",
type: "success",
};
},
// it will be called when the mutation is failed
errorNotification: (data, values, resource) => {
return {
message: `Something went wrong when getting ${data.id}`,
description: "Error",
type: "error",
};
},
});

With i18n
Check the guide
Please check the guide for more information on this topic.

Refine's notification integration is also integrated with the i18n Provider. This means that you can use the i18n integration to customize the notifications.

Refine uses following keys for the notifications and popultes {{resource}} and {{statusCode}}. You can override these keys in your i18n provider to customize the notifications.

/locales/en/common.json
{
"notifications": {
"success": "Successful",
"error": "Error (status code: {{statusCode}})",
"undoable": "You have {{seconds}} seconds to undo",
"createSuccess": "Successfully created {{resource}}",
"createError": "There was an error creating {{resource}} (status code: {{statusCode}})",
"deleteSuccess": "Successfully deleted {{resource}}",
"deleteError": "Error when deleting {{resource}} (status code: {{statusCode}})",
"editSuccess": "Successfully edited {{resource}}",
"editError": "Error when editing {{resource}} (status code: {{statusCode}})",
"importProgress": "Importing: {{processed}}/{{total}}"
}
}