App Extensions: Guide
This guide describes how to get started developing App Extensions. It contains the following:
- An App Extensions-flavored variation on setting up a draft app
- Example requests and responses for the App Extensions mutations and query
- Implementation and code examples
Prerequisites
Before getting started working with App Extensions, make sure you have the following:
- A BigCommerce store; we recommend using a sandbox store or other non-production store.
- A Developer Portal (opens in a new tab) account registered to the same email account that owns the sandbox store.
- General familiarity with developing BigCommerce apps. To familiarize yourself, see the Apps Guide or Apps Quick Start.
OAuth scopes
Use an app-level API account to make App Extensions API calls. Neither store-level nor account-level API accounts can manage App Extensions.
The following section describes the process for creating an app profile and app-level API account. Configure the following OAuth scopes as directed in Setup:
Name | Permission | Parameter | Description |
---|---|---|---|
App Extensions | manage | store_app_extensions_manage | Manage App Extensions; requires an app-level API account |
Other | As needed for the app to function; for a list, see OAuth scopes. |
Setup
Unlike store-level API accounts, you can edit an app-level API account's list of authorized scopes during development.
Create an app profile
Generate an app-level API account by creating an app profile in a Developer Portal account (opens in a new tab) registered to the same email account that owns the development store.
Add the required OAuth scopes from the preceding section on the Technical tab of the app profile dialog, then click Update & Close.
For more information on creating app profiles, see Managing Apps in the Developer Portal.
The following image shows the App Extensions : manage
scope on the Technical tab of the Developer Portal's app profile dialog:
Create a draft app
You can fork our Next.js starter app (opens in a new tab) to get started quickly.
After you clone the starter app repository, start the development server (opens in a new tab) and serve the draft app over https using ngrok.
For more information on persisting ngrok tunnels longer, see ngrok configuration.
For more information on working with draft apps, see the Apps Quick Start or Apps Guide.
git clone git@github.com:bigcommerce/sample-app-nodejs.git app-with-extensions
cd app-with-extensions
npm install
npm run dev
# open new terminal window
npm install ngrok
ngrok http 3000
Edit the draft app's environment variables
Copy .env-sample
and rename it .env
. Add the app profile's client ID and client secret. Select a database type and enter your connection credentials. Configure the app callback URLs by replacing the domain name (opens in a new tab) segment of the pre-populated auth callback URL with the ngrok instance's domain name. For more on configuring additional environment variables, see the starter app README (opens in a new tab) and .env-sample (opens in a new tab).
For more information on working with app environment variables, see the Apps Quick Start.
#Get the Client ID and Secret from the Developer Portal
# https://developer.bigcommerce.com/api-docs/apps/quick-start#register-a-draft-app
CLIENT_ID={app client id}
CLIENT_SECRET={app secret}
# Test locally with ngrok
# https://developer.bigcommerce.com/api-docs/apps/guide/development#testing-locally-with-ngrok
AUTH_CALLBACK=https://{ngrok_url}/api/auth
# Replace jwt key with a 32+ random character secret
JWT_KEY={SECRET}
# Specify the type of database
DB_TYPE=firebase
# If using firebase, enter your config here
FIRE_API_KEY={firebase key}
FIRE_DOMAIN={firebase domain}
FIRE_PROJECT_ID={firebase project id}
# If using mysql, enter your config here
MYSQL_HOST={mysql host}
MYSQL_DATABASE={mysql database name}
MYSQL_USERNAME={mysql username}
MYSQL_PASSWORD={mysql password}
MYSQL_PORT={mysql port *optional*}
# BigCommerce API URL
API_URL=api.bigcommerce.com
Seed the database
Use the starter app's db:setup script (opens in a new tab), then restart the development server.
npm run db:setup
npm run dev
Add the ngrok callback URLs to the app profile
Copy the ngrok domain name from the .env
file to the matching inputs on the Technical tab of the app profile.
Install the draft app on your store
For directions, see the Apps Quick Start.
Example requests
This section contains examples of App Extensions-related GraphQL Admin API queries and mutations. It presents mutations and their variables separately. You can use a tool like Postman (opens in a new tab) or Altair (opens in a new tab) to make requests; if you prefer to get started quickly in Postman, see the App Extensions Postman collection.
Use the following HTTP configuration to send requests:
POST https://api.bigcommerce.com/stores/{{store_hash}}/graphql
X-Auth-Token: {{access_token}}
Accept: application/json
Content-Type: application/json
The following examples direct you to stringify the GraphQL query portion of your requests, but how this works in practice varies depending on the client you use.
Create an App Extension
The createAppExtension mutation registers an App Extension that opens a side panel on the store control panel's customers page to let users read and write notes about interactions with specific customers.
mutation AppExtension($input: CreateAppExtensionInput!) {
appExtension {
createAppExtension(input: $input) {
appExtension {
id
context
model
url
label {
defaultValue
locales {
value
localeCode
}
}
}
}
}
}
Get a store's App Extensions
The Store appExtensions query returns a list of the store's App Extensions registered to the API account that makes the request, along with any details requested using the query schema. Note that all GraphQL requests use the POST
method.
query {
store {
appExtensions {
edges {
node {
id
url
model
}
}
}
}
}
Update an App Extension
The updateAppExtension mutation can update the label
object and the url
of an existing App Extension. All other properties are non-mutable.
Changes to the label
object overwrite existing values, rather than upserting. Be sure to send the full label object you intend the App Extension to have.
Note that the UpdateAppExtensionInput
has two properties, id
and data
. Add the desired new values for the url
or label
properties to the data
attribute.
mutation AppExtension($input: UpdateAppExtensionInput!) {
appExtension {
updateAppExtension(input: $input) {
appExtension {
id
url
label {
defaultValue
}
}
}
}
}
Delete an App Extension
The deleteAppExtension mutation deletes an App Extension. It cannot be recovered. Note that you can request an additional property that isn't accessible to the other queries and mutations, deletedAppExtensionId
. You can't request any other properties in the delete mutation.
mutation AppExtension($input: DeleteAppExtensionInput!) {
appExtension {
deleteAppExtension(input: $input) {
deletedAppExtensionId
}
}
}
Example code
Starter app
The BigCommerce Next.js starter app (GitHub) (opens in a new tab) contains a branch that features a working, end-to-end App Extensions reference implementation.
Code sample
The following Node.js code sample uses the node-fetch http request package (opens in a new tab) to create a color picker App Extension that opens in a side panel on the View Products page of the merchant's store control panel.
import setAppExtension from "./set-app-extension";
// Hardcoded example of store-specific credentials
const subjectStore = {
store_hash: "qwerty",
// the store's access_token from your DB
access_token: "xxxxxalphanumxxxxx"
};
// stringified GraphQL Mutation
const registerAppExtensionMutation = `
mutation AppExtension($input: CreateAppExtensionInput!) {
appExtension {
createAppExtension(input: $input) {
appExtension {
id
context
model
url
label {
defaultValue
locales {
value
localeCode
}
}
}
}
}
}
`;
// This GraphQL variable describes the particular App Extension your app is registering; modify for your use case
const colorPickerExtension = {
input: {
context: "PANEL",
model: "PRODUCTS",
url: "/product/${id}/pigment",
label: {
defaultValue: "Select Color",
locales: [
{
value: "Pick Color",
localeCode: "en-US"
},
{
value: "Choisissez la couleur",
localeCode: "fr-FR"
},
],
},
},
};
return setAppExtension(
subjectStore,
registerAppExtensionMutation,
colorPickerExtension
);