RPC methods
Overview
The SCAYLE Storefront is built upon a foundation of Remote Procedure Call (RPC) methods. These are JavaScript functions that adhere to a defined interface and are registered with the RPC system. This approach allows us to encapsulate business logic into reusable functions, exposed through an automatically generated API. As a result, developers can easily integrate this functionality without the overhead of building and managing REST APIs. TypeScript provides automatic type checking for parameters and return values, enhancing reliability.
Universal Rendering
Nuxt offers several rendering modes, with Universal Rendering being the most common. This mode renders Vue components on both the server and the client. However, RPC methods are executed exclusively on the server.
- During Server-Side Rendering (SSR): Calling an RPC method directly executes its corresponding function on the server.
- On the Client-Side: Calling an RPC method triggers an HTTP request to the server. The server then executes the method and returns the result.
This process is handled automatically, providing a consistent API for calling RPC methods regardless of the rendering context. In the Storefront Application, all calls to SCAYLE APIs are made within RPC methods. This server-side execution protects sensitive API tokens from client exposure and keeps certain implementation details private.
Rendering a Page on the Server
Consider the useProduct
composable, which can be used during both server-side rendering and on the client. It relies on the getProduct
RPC method. Because getProduct
executes on the server, it has secure access to the API token and can call the Storefront API. Furthermore, most RPC methods leverage caching to reduce latency and minimize the load on the Storefront API.

Storefront Core API Example
Custom RPC Methods
Storefront applications can define and implement custom RPC methods, which are then callable within the application. These custom RPCs have access to the RPCContext, providing information about the session, shop, and secure tokens.
Creating a custom RPC method is recommended when integrating with external services, such as SCAYLE add-ons or third-party providers. This approach also helps prevent sensitive code and data from being exposed to the client.
To create a custom RPC method, simply add a new file to the rpcMethods
directory of your project:
This example demonstrates creating an RPC method called getShopId
, which returns the shop identifier from the context. This RPC takes no input arguments and fulfills the RPC contract.
It's crucial to export the getShopId
function from its file and from the rpcMethods/index.ts
file. To export from rpcMethods/index.ts
, add the following line:
Passing Arguments to RPC Methods
RPC methods can accept parameters. Define these parameters as the first argument of your RPC function. The RpcContext
remains the second argument. You'll also need to update the satisfies RpcHandler<Input, Output>
declaration to reflect the input and output types.
This example defines the subscribeToNewsletter
RPC method, which accepts an email address and (currently) returns it after subscribing the user to a newsletter. The RpcHandler
type declaration specifies the input type ({ email: string }
) and the output type (string
).
Registering Custom RPC Methods
In order for a custom RPC method to be usable, it must be registered. Registration will create the necessary API endpoint for the RPC and extend the global types to include the RPC. The process of registering an RPC method changes depending on whether you are creating a custom RPC method within the Storefront Application or as part of a Nuxt module.
Within a Storefront Application
To register an RPC method in a Storefront Application, you must define rpcDir
and rpcMethodNames
in the module configuration (within your nuxt.config.ts
or a relevant module setup). rpcDir
defines the directory from where the method functions will be imported, and rpcMethodNames
is a list of the identifiers to import and register as RPC methods.
Overriding Core RPC Methods
The Storefront SDKs also include their own set of RPCs. This introduces the possibility of name conflicts, which could result in accidentally overriding an existing RPC method.
- Warning: In such cases, you will receive a warning in your console indicating which RPC method was overridden, as this can lead to unexpected side effects and cause the application to behave improperly.
- Caution: Overriding core RPC methods should be done with extreme caution and only when absolutely necessary. If an RPC method is overridden, we cannot guarantee that the Storefront SDKs will work as expected. It becomes your responsibility to test all relevant cases thoroughly.
- Silencing Warnings: To suppress console warnings for intended overrides, add the overridden RPC method's name to the
storefront.rpcMethodOverrides
configuration in yournuxt.config.ts
.
Within a Nuxt Module
Nuxt modules can also register custom RPC methods. For a module to register a custom RPC method, they should register for the storefront:custom-rpc:extend
hook and append their RPC method import definitions. An import definition includes the source file and the export names to register as RPC methods.
The registration of RPC methods via this hook is slightly more restrictive:
- If a hook-registered RPC method uses the same name as an application-registered RPC method, the application-registered one will take precedence.
- RPC methods registered via this hook are not allowed to override core RPC methods from the Storefront SDKs.
Source | Priority | Can Override Core RPCs? | Location |
---|---|---|---|
Core RPC Method | Medium | n/a | storefront-core package |
storefront:custom-rpc:extend | Low | No | Nuxt module (or application) |
`rpcDir`/`rpcMethodNames` | Highest | Yes | Application |
Calling Custom RPC Methods
After defining and registering your custom RPC methods, you need a way to call them from your components or composables. Two options are available, depending on your needs:
- useRpc: This composable provides a declarative approach for calling RPCs within pages, components, or other composables. It's suitable for calls that should occur during initial setup or data fetching.
useRpc
behaves similarly touseAsyncData
. - useRpcCall: Use this composable when triggering an RPC in response to an event or user interaction (e.g., clicking a button, submitting a form).
useRpcCall
is more akin to$fetch
.
Both useRpc
and useRpcCall
are composables and must follow composable usage rules. For further guidance, refer to Nuxt's data fetching guide.
useRpc
useRpc
offers a declarative approach to data fetching. It handles the fetch state, automatically executes the RPC method, and returns the result or any errors. Many Storefront Core composables utilize useRpc
as lightweight wrappers around provided RPCs.
Here's how to call the getShopId
RPC from the previous example:
The first argument to useRpc
is the RPC method name (the name under which the RPC is exported). The second argument is a unique key, which Nuxt uses to avoid redundant fetches and repopulate server-side rendered data. For more details, consult the Nuxt documentation or check out the "Nuxt 3.8 - Client-side caching with getCachedData" YoutTube video by Alexander Lichter, a Core Nuxt Maintainer.
We recommend using location-specific unique keys and explicitly passing data rather than assuming key usage and fetch behavior elsewhere.
The third (optional) argument provides parameters to the RPC method. In this example, getShopId
doesn't require parameters. If parameters are needed, you can pass a reactive function or a computed value. useRpc
will automatically re-fetch the data if any of the reactive parameters change.
Managing Shared State with useRpc
By default, useRpc
utilizes a shared cache, causing all instances called with the same key to share the same data. You can disable this behavior globally by setting the disableDefaultGetCachedDataOverride
option in the public runtime config.
You can also disable this behavior for individual useRpc
calls:
If disabled globally, you can re-enable shared caching for specific useRpc
calls:
useRpcCall
useRpcCall
is designed for calling RPCs in response to events or user interactions, such as clicking a button or submitting a form. Consider the subscribeToNewsletter
example, triggered by a form submission:
useRpcCall
accepts the RPC method name and returns a callback function. When invoked, this callback receives the RPC parameters, makes the request, and returns a promise that resolves with the RPC's response.
RPC Context
The RPC context object provides information about the current application, including application secrets and helper functions for RPCs. Key properties and methods include:
Property Name | Description |
---|---|
sapiClient | A reference to the Storefront API client initialized to the shop of the request. |
campaignKey | The key for the currently active campaign. By default, we will choose any active campaign at the time of the request. |
cached | A utility function for caching functions. |
user | The current user. |
wishlistKey | The wishlist identifier for the current session. |
basketKey | The basket identifier for the current session. |
sessionId | The unique session id of the current user. |
shopId | The shop id of the current request. |
log | A reference to the logger. |
runtimeConfiguration | An object containing the private properties set at runtime through the environment. |
Extending the RPC Context
You can add custom information to the RPC context to make it available to all your RPC methods. This is achieved by hooking into the storefront:context:created
Nitro runtime hook.
Create a server plugin and register a hook using nitroApp.hooks.hook('storefront:context:created', handler)
. The handler
is a synchronous or asynchronous function that receives the base RPCContext
as its argument. You can modify the context passed to RPC methods by adding or changing properties on this object.
Caution: Overwriting existing RPCContext
properties is strongly discouraged, as it can break application functionality. Proceed with extreme care if you choose to do so.
Adding a New Property
To add a new property to the PRC Context, use the following snippet:
Overwriting Existing Values
While possible, overwriting or changing existing values within the RPC context is generally not recommended and should be done with extreme caution. If absolutely necessary, use the following approach: