Frappe React Sdk

React hooks for Frappe

Install Frappe React Sdk

bench get-app https://github.com/frappe/frappe-react-sdk

Tags

  • frappe
  • react

Add the Frappe Gems badge to your README

Maintain Frappe React Sdk? Paste this into your README:

[![Listed on Frappe Gems](https://frappegems.com/api/method/frappe_gems.seo.badge?app=frappe%2Ffrappe-react-sdk)](https://frappegems.com/gems/apps/frappe/frappe-react-sdk)

About Frappe React Sdk

# frappe-react-sdk React hooks library for a [Frappe Framework](https://frappeframework.com) backend.

## Features The library currently supports the following features: - 🔐 Authentication - login with username and password (cookie based) + token based authentication, logout and maintain user state - 🗄 Database - Hooks to get document, get list of documents, get count, create, update and delete documents - 📄 File upload - Hook to upload a file to the Frappe filesystem. Maintains loading, progress and error states. - 🤙🏻 API calls - Hooks to make API calls to your whitelisted backend functions and maintain state - 🔍 Search - Hook to search documents in your database (with debouncing ✨) We plan to add the following features in the future: - Support for other common functions like `exists` in the database. The library uses [frappe-js-sdk](https://github.com/The-Commit-Company/frappe-js-sdk) and [SWR](https://swr.vercel.app) under the hood to make API calls to your Frappe backend.
## SWR SWR uses a cache invalidation strategy and also updates the data constantly and automatically (in the background). This allows the UI to always be fast and reactive. The hooks in the library use the default configuration for useSWR but you will be able to overwrite the configuration of useSWR. Please refer to the [useSWR API Options](https://swr.vercel.app/docs/options)
## Looking for a Frappe frontend library for other Javascript frameworks? You can use [frappe-js-sdk](https://github.com/The-Commit-Company/frappe-js-sdk) to interface your frontend web app with Frappe.
## Maintainers | Maintainer | GitHub | Social | | -------------- | ----------------------------------------------- | ------------------------------------------------------------ | | Nikhil Kothari | [nikkothari22](https://github.com/nikkothari22) | [@nik_kothari22](https://twitter.com/nik_kothari22) | | Janhvi Patil | [janhvipatil](https://github.com/janhvipatil) | [@janhvipatil\_](https://twitter.com/janhvipatil_) | | Sumit Jain | [sumitjain236](https://github.com/sumitjain236) | [LinkedIn](https://www.linkedin.com/in/sumit-jain-66bb5719a) |
## Installation ```bash npm install frappe-react-sdk ``` or ```bash yarn add frappe-react-sdk ``` **Note** - All examples below are in Typescript. If you want to use it with Javascript, just ignore the type generics like `` in the examples below.
## Initialising the library To get started, initialise the library by wrapping your App with the `FrappeProvider`. You can optionally provide the URL of your Frappe server if the web app is not hosted on the same URL. In `App.tsx` or `App.jsx`: ```jsx import { FrappeProvider } from "frappe-react-sdk"; function App() { /** The URL is an optional parameter. Only use it if the Frappe server is hosted on a separate URL **/ return ( {/** Your other app components **/} ) ``` In case you want to use the library with token based authentication (OAuth bearer tokens or API key/secret pairs), you can initialise the library like this: ```jsx import { FrappeProvider } from 'frappe-react-sdk'; function App() { /** The URL is an optional parameter. Only use it if the Frappe server is hosted on a separate URL **/ return ( {/** Your other app components **/} ); } ```
## Authentication The `useFrappeAuth` hook allows you to maintain the state of the current user, as well as login and logout the current user. The hook uses `useSWR` under the hood to make the `get_current_user` API call - you can also pass in parameters to configure the behaviour of the useSWR hook. ```jsx export const MyAuthComponent = () => { const { currentUser, isValidating, isLoading, login, logout, error, updateCurrentUser, getUserCookie, } = useFrappeAuth(); if (isLoading) return
loading...
; // render user return (
{currentUser}
); }; ``` The hook will not make an API call if no cookie is found. If there is a cookie, it will call the `frappe.auth.get_logged_user` method. The hook will throw an error if the API call to `frappe.auth.get_logged_user` fails (network issue etc) or if the user is logged out (403 Forbidden). Handle errors accordingly and route the user to your login page if the error is because the user is not logged in. The `getUserCookie` method can be used to reset the auth state if you encounter an authorization error in any other API call. This will then reset the `currentUser` to null.
## Database
### Fetch a document The `useFrappeGetDoc` hook can be used to fetch a document from the database. The hook uses `useSWR` under the hood and it's configuration can be passed to it. Parameters: | No. | Variable | type | Required | Description | | --- | --------- | ------------------ | -------- | ------------------------- | | 1. | `doctype` | `string` | ✅ | Name of the doctype | | 2. | `docname` | `string` | ✅ | Name of the document | | 3. | `options` | `SWRConfiguration` | - | SWR Configuration Options | ```tsx export const MyDocumentData = () => { const { data, error, isValidating, mutate } = useFrappeGetDoc( 'User', 'Administrator', { /** SWR Configuration Options - Optional **/ } ); if (isValidating) { return <>Loading; } if (error) { return <>{JSON.stringify(error)}; } if (data) { return (

{JSON.stringify(data)}

); } return null; }; ```

### Fetch list of documents The `useFrappeGetDocList` hook can be used to fetch a list of documents from the database. Parameters: | No. | Variable | type | Required | Description | | --- | --------- | ------------------ | -------- | --------------------------------------------------------------------------------------------------- | | 1. | `doctype` | `string` | ✅ | Name of the doctype | | 2. | `args` | `GetDocListArgs` | - | optional parameter (object) to sort, filter, paginate and select the fields that you want to fetch. | | 3. | `options` | `SWRConfiguration` | - | SWR Configuration Options | ```tsx export const MyDocumentList = () => { const { data, error, isValidating, mutate } = useFrappeGetDocList( 'DocType', { /** Fields to be fetched - Optional */ fields: ['name', 'creation'], /** Filters to be applied - SQL AND operation */ filters: [['creation', '>', '2021-10-09']], /** Filters to be applied - SQL OR operation */ orFilters: [], /** Fetch from nth document in filtered and sorted list. Used for pagination */ limit_start: 5, /** Number of documents to be fetched. Default is 20 */ limit: 10, /** Sort results by field and order */ orderBy: { field: 'creation', order: 'desc', }, /** Fetch documents as a dictionary */ asDict: false, }, { /** SWR Configuration Options - Optional **/ } ); if (isValidating) { return <>Loading; } if (error) { return <>{JSON.stringify(error)}; } if (data) { return (

{JSON.stringify(data)}

); } return null; }; ``` Type declarations are available for the second argument and will be shown to you in your code editor.

#### Some other simpler examples (click to expand):
Fetch 20 items without optional parameters

In this case, only the `name` attribute will be fetched. ```tsx export const MyDocumentList = () => { const { data, error, isValidating } = useFrappeGetDocList('User'); if (isValidating) { return <>Loading; } if (error) { return <>{JSON.stringify(error)}; } if (data) { return (

    {data.map((username) => (
  • {username}
  • ))}
); } return null; }; ```

Fetch usernames and emails with pagination

```tsx type UserItem = { name: string, email: string } export const MyDocumentList = () => { const [pageIndex, setPageIndex] = useState(0) const { data, error, isValidating } = useFrappeGetDocList("User" , { fields: ["name", "email"], limit_start: pageIndex, /** Number of documents to be fetched. Default is 20 */ limit: 10, /** Sort results by field and order */ orderBy: { field: "creation", order: 'desc' } }); if (isValidating) { return <>Loading } if (error) { return <>{JSON.stringify(error)} } if (data) { return

    { data.map({name, email} =>
  • {name} - {email}
  • ) }
} return null } ```




### Fetch number of documents with filters
Parameters: | No. | Variable | type | Required | Description | | --- | --------- | ------------------ | -------- | -------------------------------------------------------------- | | 1. | `doctype` | `string` | ✅ | Name of the doctype | | 2. | `filters` | `Filter[]` | - | optional parameter to filter the result | | 3. | `debug` | `boolean` | - | Whether to log debug messages on the server - default: `false` | | 4. | `config` | `SWRConfiguration` | - | SWR Configuration Options | ```tsx export const DocumentCount = () => { const { data, error, isValidating, mutate } = useFrappeGetDocCount( 'User', /** Filters **/ [['enabled', '=', true]], /** Print debug logs on server **/ false, { /** SWR Configuration Options - Optional **/ } ); if (isValidating) { return <>Loading; } if (error) { return <>{JSON.stringify(error)}; } if (data) { return (

{data} enabled users

); } return null; }; ``` #### Some other simpler examples (click to expand):
Fetch total number of documents

```tsx export const DocumentCount = () =>

Related Integrations apps for Frappe & ERPNext

  • Insights — Open Source Business Intelligence Tool
  • Raven — Simple, open source team messaging platform
  • Frappe Whatsapp — WhatsApp cloud integration for frappe
  • Frappe Assistant Core — Infrastructure that connects LLMs to ERPNext. Frappe Assistant Core works with the Model Context Protocol (MCP) to expose ERPNext functionality to any compatible Language Model
  • Biometric Attendance Sync Tool — A simple tool for syncing Biometric Attendance data with your ERPNext server
  • Frappe Js Sdk — TypeScript/JavaScript library for Frappe REST API
  • Mcp — Frappe MCP allows Frappe apps to function as MCP servers
  • Erpnext Shipping — A Shipping Integration for ERPNext