Access Record Data with Data SDK (Beta)
While Agentfoce Vibes automatically generates code for data access, it's helpful to understand how you can write your own code to access Salesforce data from your React web app via the Data SDK.
Data SDK provides several advantages for data access, including environment adaptability and type safety.
- Abstraction and consistency: The SDK abstracts environment-specific APIs, so you call a simple method and the SDK handles the implementation details for the specific host environment, for example, Lightning Experience or an Experience Builder site.
- Capability detection: The SDK includes integrated capability detection to identify the runtime environment, infer its capabilities, and determine the concrete way to implement those capabilities. Given the built-in detection, component authors can code safely across deployment scenarios.
- Modern developer experience: The SDK provides full TypeScript definitions to offer IntelliSense and autocomplete functionality, compile-time type safety, and uses Promises for structured error handling (try/catch blocks) instead of loosely-typed events.
When using the Data SDK to access Salesforce data use standard web APIs and npm packages only. These functionalities aren't supported:
@salesforcescoped modules, except@salesforce/sdk-data- Lightning base components and lightning/* modules
- @wire service
Use the @salesforce/sdk-data for all Salesforce API calls. The SDK handles authentication and CSRF validation. Follow these data access guidelines in order of preference.
- Use GraphQL queries and mutations as the preferred way to access data.
dataSdk.graphql?.()sends a POST request to Salesforce GraphQL. - Use UI API via
sdk.fetch?()for data access that calls/services/data/v{version}/ui-api/*or another Salesforce REST endpoint, such as an Apex controller that's exposed via Apex REST. - Use GraphQL with
sdk.fetch?()if GET request is required, such as when your query and variables are small enough to fit in URL constraints. Or use a GraphQL GET request if you have a dependency on a roundtrip fetch of a CSRF token. - Use Apex REST when you want custom logic that GraphQL doesn't support.
- Don't call
fetch()oraxiosdirectly for Salesforce endpoints.
Review the examples in the React App Recipes GitHub repo. Install the app in a scratch org and explore each recipe to understand how to complete a specific task, whether it's querying data with GraphQL or handling loading, an empty state, or error responses.
The Data SDK handles authentication, CSRF tokens, and base path resolution internally.
With the Data SDK, you can query and update Salesforce records extensively from your web app by using simple bindings for running GraphQL queries and mutations.
| Export | Type | Description |
|---|---|---|
createDataSDK | async function | Factory that creates a new DataSDK instance |
gql | template tag | Identity template literal for inline GraphQL queries, which also enables editor syntax highlighting and codegen detection |
DataSDK | interface | The SDK surface type with graphql and fetch methods |
SDKOptions | interface | Base options type with optional surface override |
NodeOfConnection<T> | utility type | Extracts the node type from a GraphQL connection with edges and node response |
Creates a new DataSDK instance.
options:DataSDKOptions-Optional configuration forcreateDataSDK
DataSDKOptions
surface:string-For automatic surface detectionwebapp: WebAppDataSDKOptions-Options specific to the web app surface
WebAppDataSDKOptions
basePath:string-Base URL prefix for Salesforce API callson401:() => Promise<unknown> | void-Optional callbackon403:() => Promise<unknown> | void-Optional callback
The return type for createDataSDK(options?), which resolves to a promise with the DataSDK object.
The gql tag is a template literal for inline GraphQL query definitions. When GraphQL queries are defined with TypeScript code, the Data SDK requires the use of gql to understand and apply special processing to your GraphQL queries at different stages of the component lifecycle. The use of the gql tag enables org-aware GraphQL syntax highlighting when using Agentforce Vibes.
See GraphQL Usage in Data SDK.
Both graphql and fetch methods are optional as they're supported in specific environments only.
GraphQL is the preferred way to work with record data.
To account for the lack of availability of GraphQL in some environments, use optional chaining (graphql?). See GraphQL Usage in Data SDK.
Use dataSdk.fetch?() for Salesforce REST endpoints that are not covered by GraphQL. Use optional chaining to account for environments that don't support fetch().
The fetch wrapper handles:
- CSRF token management
- Base path resolution
- 401/403 callback hooks
Consider using the dataSdk.fetch() call for:
- Apex REST endpoints (e.g. /services/apexrest/auth/...)
- Salesforce REST endpoints (e.g. /services/data/v{version}/...)
These API endpoints are supported.
- /services/apexrest
- /services/data/v{version}/ui-api/records
- /services/data/v{version}/ui-api/search-info
- /services/data/v{version}/ui-api/layout
- /services/data/v{version}/ui-api/session/csrf
- /services/data/v{version}/connect/file/upload/config
- /services/data/v{version}/connect/proxy/ui-telemetry
- /services/data/v{version}/chatter/users/me
- /services/data/vs{version}/chatter/users/{userId}
- /sfsites/c/_nc_external/system/security/session/SessionTimeServlet
- /secur/logout.jsp
We recommend that you use optional chaining fetch?() instead of a non-null assertion fetch!(). Optional chaining is useful when you want to use fetch in a shared or cross-surface utility. If you're not sure where your code is run, use optional chaining and handle the response appropriately.
The read-data examples in the Multi-framework recipes repo demonstrate how to call Chatter Connect API, Apex REST, and UI API REST.
Extracts the node type from a UIAPI connection response shape with the edges and node pattern.
Use NodeOfConnection when your GraphQL response uses the Salesforce connection shape (edges and node) and you want a clean, strongly-typed node type. For example:
- Query returns:
Account { edges { node { ... } } } - You define:
type AccountNode = NodeOfConnection<MyQuery["uiapi"]["query"]["Account"]> - Use
AccountNodefor transforms, props, and list rendering
If your query doesn't use connection fields or you already have simple flat generated types, you don’t need to use NodeOfConnection.
Runs a GraphQL request.
Parameters:
query:string-The GraphQL query or mutation operation.variables?: V, Defaults toRecord<string, unknown>-Optional key-value map of GraphQL variables that's referenced by the query.
The return type of dataSdk.graphql?.(), which resolves to the typed GraphQL response payload.
GraphQL record queries return this response structure.