For security reasons, app instance ID (instanceId
) isn’t directly accessible in site widgets or settings panels. Instead, you can securely extract it by sending a Wix access token to a backend API. The backend can decode the token, get the instance ID or instance data, and perform any necessary business logic.
This article explains how to:
To securely identify the app instance:
Expose a backend API. You can build and deploy your backend API using any framework. The examples in this article are based on a Node.js server.
In your backend API code, get the Wix access token from the authorization
header.
const accessToken = req.headers["authorization"];
Depending on your use case, you may only need instanceId
or you may need more detailed app instance data.
To extract instanceId
:
Call Get Token Info to extract instanceId
from the access token.
const tokenResponse = await axios.post(
"https://www.wixapis.com/oauth2/token-info",
{
token: accessToken,
},
);
const instanceId = tokenResponse.data.instanceId;
To fetch instance data:
Elevate the access token to an app identity. Then, call Get App Instance (SDK | REST). Elevation is necessary because access tokens sent from site widgets are tied to a site visitor or member identity, which don't have access to instance data.
The method of performing elevation varies depending on whether you're using the JavaScript SDK or REST API.
JavaScript SDK
const elevatedClient = createClient({
auth: await AppStrategy({
appId: "<YOUR_APP_ID>",
appSecret: "<YOUR_APP_SECRET>",
accessToken: accessToken,
}).elevated(),
modules: {
appInstances,
},
});
const instanceResponse = await elevatedClient.appInstances.getAppInstance();
To learn more, see Elevate SDK Call Permissions with Self-Hosting.
REST API
// Extract the app instance ID from the access token
const tokenResponse = await axios.post(
"https://www.wixapis.com/oauth2/token-info",
{
token: accessToken,
},
);
const instanceId = tokenResponse.data.instanceId;
// Create a new access token with an app identity
const newTokenResponse = await axios.post(
"https://www.wixapis.com/oauth2/token",
{
grant_type: "client_credentials",
client_id: "<YOUR_APP_ID>",
client_secret: "<YOUR_APP_SECRET>",
instanceId: instanceId,
},
);
const elevatedAccessToken = newTokenResponse.data.access_token;
// Use the new token to get instance data
const instanceResponse = await axios.get(
"https://www.wixapis.com/apps/v1/instance",
{
headers: {
Authorization: `Bearer ${elevatedAccessToken}`,
},
},
);
To learn more, see Elevate REST API Call Permissions with Self-Hosting.
To pass a Wix access token from your custom element to your backend:
Add a self-hosted site widget extension with a custom element. If you already have a site widget, skip to the next step.
In your custom element code, initialize a WixClient
with the site authentication and host configuration.
const myWixClient = createClient({
auth: site.auth(),
host: site.host({ applicationId: "<YOUR_APP_ID>" }),
});
Add the following line to the constructor of your custom element class to inject the Wix access token.
this.accessTokenListener = myWixClient.auth.getAccessTokenInjector();
Import the httpClient
submodule from the Essentials SDK.
import { httpClient } from "@wix/essentials";
Call fetchWithAuth()
to send the access token to your backend.
const response = await myWixClient.fetchWithAuth("<YOUR_API_URL>");
Tip: To get instanceId
in the settings panel, initialize a WixClient
with the editor authentication and host configuration. Then, call fetchWithAuth()
.
Depending on your use case, the logic of your backend API will vary. For example, you may only need to extract instanceId
and then use it to make a request to your own database. Alternatively, you may wish to request app instance data from Wix, in which case you'd need to elevate your access token.
See the relevant example for your use case:
instanceId
instanceId
The following example creates a Node.js Express API called get-instance
. The API extracts instanceId
from the access token provided by the frontend request.
import express from "express";
import axios from "axios";
import cors from "cors";
const app = express();
const port = 5000;
app.use(cors());
// Edit this code based on your business logic
const mockDatabaseQuery = async (instanceId) => {
console.log(`Mock database query with instance ID: ${instanceId}`);
if (instanceId) {
return {
status: "Success",
};
} else {
return {
status: "No instance ID.",
};
}
};
// Define a backend API
app.get("/get-instance", async (req, res) => {
try {
// Get the Wix access token from the `authorization` header
const accessToken = req.headers["authorization"];
if (!accessToken) {
throw new Error("Access token is required.");
}
// Extract the app instance ID from the access token
const tokenData = await axios.post(
"https://www.wixapis.com/oauth2/token-info",
{
token: accessToken,
},
);
const instanceId = tokenData.data.instanceId;
console.log("Instance ID:", instanceId);
// Edit this code based on your business logic
const data = await mockDatabaseQuery(instanceId);
return res.json(data);
} catch (error) {
console.error("Error processing request:", error.message);
return res.status(500).json({ error: "Failed to process request" });
}
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
The following example creates a Node.js Express API called get-instance
. The API receives an access token from the frontend, creates a client with elevated permissions, and then uses the elevated client to fetch the app instance data.
import express from "express";
import cors from "cors";
import { createClient, AppStrategy } from "@wix/sdk";
import { appInstances } from "@wix/app-management";
const app = express();
const port = 5000;
app.use(cors());
// Define a backend API
app.get("/get-instance", async (req, res) => {
try {
// Get the Wix access token from the `authorization` header
const accessToken = req.headers["authorization"];
if (!accessToken) {
throw new Error("Access token is required.");
}
const elevatedClient = createClient({
auth: await AppStrategy({
appId: "<YOUR_APP_ID>",
appSecret: "<YOUR_APP_SECRET>",
accessToken: accessToken,
}).elevated(),
modules: {
appInstances,
},
});
const instanceResponse = await elevatedClient.appInstances.getAppInstance();
return res.json(instanceResponse.data);
} catch (error) {
console.error("Error processing request:", error.message);
return res.status(500).json({ error: "Failed to process request" });
}
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
The following example creates a Node.js Express API called get-instance
. The API receives an access token from the frontend, uses the token to request a new access token with the permissions of an app, and then uses the new elevated access token to fetch the app instance data.
import express from "express";
import axios from "axios";
import cors from "cors";
const app = express();
const port = 5000;
app.use(cors());
// Define a backend API
app.get("/get-instance", async (req, res) => {
try {
// Get the Wix access token from the `authorization` header
const accessToken = req.headers["authorization"];
if (!accessToken) {
throw new Error("Access token is required.");
}
// Extract the app instance ID from the access token
const tokenResponse = await axios.post(
"https://www.wixapis.com/oauth2/token-info",
{
token: accessToken,
},
);
const instanceId = tokenResponse.data.instanceId;
// Create a new access token with an app identity
const newTokenResponse = await axios.post(
"https://www.wixapis.com/oauth2/token",
{
grant_type: "client_credentials",
client_id: "<YOUR_APP_ID>",
client_secret: "<YOUR_APP_SECRET>",
instanceId: instanceId,
},
);
const elevatedAccessToken = newTokenResponse.data.access_token;
// Use the new token to get instance data
const instanceResponse = await axios.get(
"https://www.wixapis.com/apps/v1/instance",
{
headers: {
Authorization: `Bearer ${elevatedAccessToken}`,
},
},
);
return res.json(instanceResponse.data);
} catch (error) {
console.error("Error processing request:", error.message);
return res.status(500).json({ error: "Failed to process request" });
}
});
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
The following example creates a custom element that makes a request to the get-instance
endpoint.
import { site } from "@wix/site";
import { createClient } from "@wix/sdk";
// Create a Wix Client with site authentication and site host
const myWixClient = createClient({
auth: site.auth(),
host: site.host({ applicationId: "<YOUR_APP_ID>" }),
});
class MyCustomElement extends HTMLElement {
constructor() {
super();
// Inject the Wix access token to your custom element
this.accessTokenListener = myWixClient.auth.getAccessTokenInjector();
}
connectedCallback() {
this.innerHTML = "<p>My custom element loaded successfully!</p>";
this.callMyBackend();
}
async callMyBackend() {
try {
// Send the access token to your backend
const response = await myWixClient.fetchWithAuth(
"<YOUR_API_BASE_URL>/get-instance",
);
const data = await response.json();
console.log("Response from get-instance:", data);
} catch (error) {
console.error("Error calling get-instance:", error);
}
}
}
customElements.define("<YOUR_CUSTOM_ELEMENT_TAG_NAME>", MyCustomElement);