Utility to make WordPress REST API requests. It's a wrapper around window.fetch.
npm install @gravityforms/requestHTTP request utilities for Gravity Forms products. Provides wrappers around window.fetch for common use cases including WordPress AJAX and the Hermes GraphQL-like API.
``bash`
npm install @gravityforms/request
| Export | Description |
|--------|-------------|
| get | Simple GET request wrapper |post
| | POST request with automatic form data encoding |createHermesClient
| | Factory for Hermes API client with template literals |serialize
| | Serialize JavaScript values for Hermes queries |raw
| | Mark strings for raw insertion without serialization |args
| | Helper for object argument serialization (combines raw + serialize) |request
| (default) | Configuration-based request handler |
---
The most commonly used export. Makes POST requests to WordPress AJAX endpoints with automatic form data encoding.
`javascript
import endpoint from 'ajaxUrl'; // Webpack alias for WordPress ajaxurl
import { post } from '@gravityforms/request';
const saveData = async ( data ) => {
const response = await post( {
endpoint,
body: {
action: 'my_ajax_action',
security: window.myPlugin.nonce,
...data,
},
} );
if ( response?.data?.success ) {
console.log( 'Saved:', response.data );
} else {
console.error( 'Error:', response?.error || response?.data );
}
};
`
| Parameter | Type | Description |
|-----------|------|-------------|
| endpoint | string | The URL to POST to |body
| | object | Request body (automatically converted to FormData) |headers
| | object | Optional HTTP headers |options
| | object | Optional fetch options |
`javascript`
{
data: { ... }, // Parsed JSON response
status: 200, // HTTP status code
}
// Or on error:
{
error: Error // Error object with .detail property
}
---
Simple GET request wrapper.
`javascript
import { get } from '@gravityforms/request';
const fetchData = async () => {
const response = await get( '/wp-json/my/v1/endpoint', {
headers: { 'X-Custom-Header': 'value' },
} );
return response.json();
};
`
| Parameter | Type | Description |
|-----------|------|-------------|
| endpoint | string | The URL to fetch |params
| | object | Optional fetch options |
---
For interacting with the Hermes GraphQL-like API. Uses template literals for intuitive query construction.
Creates a configured client with query and mutation functions.
`javascript
import { createHermesClient, serialize, raw, args } from '@gravityforms/request';
const client = createHermesClient( {
endpoint: window.ajaxurl,
queryAction: 'gcrm_hermes_query',
mutationAction: 'gcrm_hermes_mutation',
security: window.gcrm.nonce,
onLoadingChange: ( isLoading ) => {
// Optional: track loading state
},
} );
`
| Option | Type | Required | Description |
|--------|------|----------|-------------|
| endpoint | string | Yes | AJAX endpoint URL |queryAction
| | string | Yes | WordPress action for queries |mutationAction
| | string | Yes | WordPress action for mutations |security
| | string | Yes | Security nonce |queryKey
| | string | No | Body key for queries (default: 'query') |mutationKey
| | string | No | Body key for mutations (default: 'mutation') |headers
| | object | No | Custom headers for all requests |options
| | object | No | Custom fetch options |onLoadingChange
| | function | No | Callback when loading state changes |
`javascript
const { query, mutation } = client;
// Simple query
const contacts = await query{
contact(limit: 10) {
id,
firstName,
lastName
}
};
// Query with interpolated values
const limit = 20;
const searchTerm = 'John';
const results = await query{
contact(limit: ${ limit }, search: ${ searchTerm }) {
id,
firstName,
lastName,
email { address, isPrimary }
}
};
// Query with nested relationships
const deals = await query{
deal(limit: ${ 50 }) {
id,
label,
value,
contact {
id,
firstName,
lastName
},
company {
id,
companyName
}
}
};`
`javascript{
// Insert
const newContact = await mutation
insert_contact(objects: ${ [ { firstName: 'John', lastName: 'Doe' } ] }) {
returning {
id,
firstName,
lastName
}
}
};
// Update
const contactId = '123';
await mutation{
update_contact(id: ${ contactId }, firstName: "Jane", lastName: "Smith") {}
};
// Delete
const idsToDelete = [ '1', '2', '3' ];
await mutation{
delete_contact(id: ${ idsToDelete }) {}
};
// Connect relationships
await mutation{
connect_company_contact(objects: ${ [ { from: companyId, to: contactId } ] }) {}
};
// Disconnect relationships
await mutation{
disconnect_company_contact(objects: ${ [ { from: companyId, to: contactId } ] }) {}
};`
---
Converts JavaScript values to Hermes query format. Used automatically in template literals but can be called directly for complex cases.
| JavaScript Type | Hermes Output |
|-----------------|---------------|
| null / undefined | null |boolean
| | true / false |number
| | 123 |string
| | "quoted string" |array
| | [item1, item2] |object
| | {key: value} |
`javascript
import { serialize } from '@gravityforms/request';
serialize( 'hello' ); // "hello"
serialize( 42 ); // 42
serialize( true ); // true
serialize( null ); // null
serialize( [ 1, 2, 3 ] ); // [1, 2, 3]
serialize( { name: 'John' } ); // {name: "John"}
`
---
Convenience function for building query/mutation argument strings from JavaScript objects. Combines serialize() and raw() for the common argument-building pattern.
`javascript
import { args } from '@gravityforms/request';
// Instead of building argument strings manually:
const argsStr = Object.entries({ limit: 10, search: 'test' })
.map(([k, v]) => ${k}: ${serialize(v)}){ contact(${ raw( argsStr ) }) { ... } }
.join(', ');
await query;
// Use args() for cleaner syntax:
await query{ contact(${ args({ limit: 10, search: 'test' }) }) { ... } };`
---
Marks a string for raw insertion without serialization. Use this when you've pre-built an argument string.
`javascript{ pipeline(${ argsStr }) { id } }
// Without raw() - becomes: pipeline("limit: 1") - WRONG!
const argsStr = 'limit: 1';
await query;`
`javascript
import { raw } from '@gravityforms/request';
// With raw() - becomes: pipeline(limit: 1) - CORRECT!
const argsStr = 'limit: 1';
await query{ pipeline(${ raw( argsStr ) }) { id } };`
`javascriptlimit: ${ filters.limit }
// Dynamic argument strings
const buildArgs = ( filters ) => {
const parts = [];
if ( filters.limit ) parts.push( );search: ${ JSON.stringify( filters.search ) }
if ( filters.search ) parts.push( );
return parts.join( ', ' );
};
const argsStr = buildArgs( { limit: 20, search: 'test' } );
await query{ contact(${ raw( argsStr ) }) { id, firstName } };
// Dynamic field/type names
const objectType = 'contact';
await mutation{
delete_${ raw( objectType ) }(id: ${ ids }) {}
};
// Dynamic field names with serialize for values
const fieldName = 'firstName';
const value = 'John';
await mutation{
update_contact(id: ${ id }, ${ raw( fieldName ) }: ${ value }) {}
};`
---
(Default Export)Configuration-based request handler. Requires endpoint configuration in gravityforms.config.js.
In your project's gravityforms.config.js:
`javascript`
module.exports = {
requestConfig: {
endpoints: {
get_entries: {
path: '/wp-json/gf/v2/entries',
rest_params: '',
nonce: null,
},
save_form: {
path: '/wp-json/gf/v2/forms',
action: 'gf_save_form',
nonce: null,
},
},
},
};
`javascript
import request from '@gravityforms/request';
// GET request
const entries = await request( 'get_entries', endpoints, {
method: 'GET',
params: { form_id: 1 },
} );
// POST request
const result = await request( 'save_form', endpoints, {
method: 'POST',
body: { title: 'My Form', fields: [ ... ] },
} );
`
---
For React applications, use @gravityforms/react-utils which provides hooks and context:
`javascript
import { useHermesTemplateContext, HermesTemplateProvider } from '@gravityforms/react-utils';
// In your app root
endpoint: window.ajaxurl,
queryAction: 'gcrm_hermes_query',
mutationAction: 'gcrm_hermes_mutation',
security: window.gcrm.nonce,
} }
>
// In components
const MyComponent = () => {
const { query, mutation, isLoading } = useHermesTemplateContext();
const fetchContacts = async () => {
const result = await query{
contact(limit: 10) { id, firstName, lastName }
};`
return result?.data?.data?.contact;
};
};
---
All request functions return errors in a consistent format:
`javascript
const response = await post( { endpoint, body } );
if ( response.error ) {
// Network error or exception
console.error( response.error.message );
console.error( response.error.detail ); // Contains endpoint, status, etc.
} else if ( ! response.data?.success ) {
// Server returned an error response
console.error( 'Request failed:', response.data );
} else {
// Success
console.log( 'Data:', response.data );
}
`
---
1. Always use post for WordPress AJAX - handles FormData encoding automatically
2. Include action and security nonce - required for WordPress AJAX handlers
3. Use template literals for Hermes - clearer syntax that matches server expectations
4. Use raw() for dynamic field names - prevents unwanted string quoting
5. Check response?.data?.success - standard WordPress AJAX success pattern
6. Provide user feedback - use snackbar or similar for success/error messages
`javascript
import { post } from '@gravityforms/request';
import { useSnackbar } from '@gravityforms/components/react/admin/modules/SnackBar';
const addSnackbarMessage = useSnackbar();
const saveItem = async ( data ) => {
const response = await post( {
endpoint,
body: {
action: 'my_action',
security: nonce,
...data,
},
} );
if ( response?.data?.success ) {
addSnackbarMessage( 'Saved successfully!' );
} else {
addSnackbarMessage( 'Failed to save', 'error' );
}
};
``