> Portal Navigation: > > - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version. > - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages). > - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`). > - Top-level index of all portals: https://dev.wix.com/docs/llms.txt > - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt ## Resource: Identify the App Instance in a Self-Hosted Site Widget ## Article: Identify the App Instance in a Self-Hosted Site Widget ## Article Link: https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/self-hosting/supported-extensions/site-extensions/site-widgets-and-plugins/identify-the-app-instance-in-a-self-hosted-site-widget.md ## Article Content: # Identify the App Instance in a Self-Hosted Site Widget For security reasons, [app instance ID](https://dev.wix.com/docs/build-apps/develop-your-app/access/app-instances/about-app-instances.md) (`instanceId`) isn’t directly accessible in [site widgets](https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/self-hosting/supported-extensions/site-extensions/site-widgets-and-plugins/add-self-hosted-site-widget-extensions-with-custom-elements.md) 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: * **Backend:** Expose a backend API to identify the app instance. * **Frontend:** Pass a Wix access token from your custom element to your backend. ## Step 1 | Expose a backend API To securely identify the app instance: 1. 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. 1. In your backend API code, get the Wix access token from the `authorization` header. ```javascript const accessToken = req.headers["authorization"]; ``` 1. Depending on your [use case](https://dev.wix.com/docs/build-apps/develop-your-app/access/app-instances/about-app-instances.md#example-use-cases-1), you may only need `instanceId` or you may need more detailed app instance data. * **To extract `instanceId`:** Call [Get Token Info](https://dev.wix.com/docs/rest/app-management/oauth-2/token-info.md) to extract `instanceId` from the access token. ```javascript 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](https://dev.wix.com/docs/rest/app-management/app-instance/get-app-instance.md). Elevation is necessary because access tokens sent from site widgets are tied to a site visitor or member [identity](https://dev.wix.com/docs/build-apps/develop-your-app/access/about-identities.md), 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** ```javascript const elevatedClient = createClient({ auth: await AppStrategy({ appId: "", appSecret: "", accessToken: accessToken }).elevated(), modules: { appInstances } }); const instanceResponse = await elevatedClient.appInstances.getAppInstance(); ``` To learn more, see [Elevate SDK Call Permissions with Self-Hosting](https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/self-hosting/elevate-sdk-call-permissions-with-self-hosting.md). **REST API** ```javascript // 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: "", client_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](https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/self-hosting/elevate-rest-api-call-permissions-for-self-hosting.md). ## Step 2 | Pass a Wix access token to your backend To pass a Wix access token from your custom element to your backend: 1. [Add a self-hosted site widget extension with a custom element](https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/self-hosting/supported-extensions/site-extensions/site-widgets-and-plugins/add-self-hosted-site-widget-extensions-with-custom-elements.md). If you already have a site widget, skip to the next step. 1. In your custom element code, initialize a [`WixClient`](https://dev.wix.com/docs/sdk/core-modules/sdk/wix-client.md) with the [site](https://dev.wix.com/docs/sdk/host-modules/site/introduction.md) authentication and host configuration. ```javascript const myWixClient = createClient({ auth: site.auth(), host: site.host({ applicationId: "" }), }); ``` 1. Add the following line to the constructor of your custom element class to inject the Wix access token. ```javascript this.accessTokenListener = myWixClient.auth.getAccessTokenInjector(); ``` 1. Call [`fetchWithAuth()`](https://dev.wix.com/docs/sdk/core-modules/sdk/wix-client.md) to send the access token to your backend. ```javascript const response = await myWixClient.fetchWithAuth(""); ```
**Tip:** To get `instanceId` in the settings panel, initialize a [`WixClient`](https://dev.wix.com/docs/sdk/core-modules/sdk/wix-client.md) with the [editor](https://dev.wix.com/docs/sdk/host-modules/editor/introduction.md) authentication and host configuration. Then, call `fetchWithAuth()`.
## Examples Depending on your [use case](https://dev.wix.com/docs/build-apps/develop-your-app/access/app-instances/about-app-instances.md#example-use-cases-1), 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: * [Backend: Extract `instanceId`](#backend-extract-instanceid) * [Backend: Fetch instance data with the JavaScript SDK](#backend-fetch-instance-data-with-the-javascript-sdk) * [Backend: Fetch instance data with the REST API](#backend-fetch-instance-data-with-the-rest-api) * [Frontend: Call your backend](#frontend-call-your-backend) ### Backend: Extract `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. ```javascript 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}`); }); ``` ### Backend: Fetch instance data with the JavaScript SDK 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. ```javascript 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: "", appSecret: "", 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}`); }); ``` ### Backend: Fetch instance data with the REST API 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. ```javascript 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: "", client_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}`); }); ``` ### Frontend: Call your backend The following example creates a custom element that makes a request to the `get-instance` endpoint. ```javascript 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: "" }), }); class MyCustomElement extends HTMLElement { constructor() { super(); // Inject the Wix access token to your custom element this.accessTokenListener = myWixClient.auth.getAccessTokenInjector(); } connectedCallback() { this.innerHTML = "

My custom element loaded successfully!

"; this.callMyBackend(); } async callMyBackend() { try { // Send the access token to your backend const response = await myWixClient.fetchWithAuth("/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("", MyCustomElement); ``` ## See also * [About Site Widget Extensions](https://dev.wix.com/docs/build-apps/develop-your-app/extensions/site-extensions/site-widgets/about-site-widget-extensions.md) * [About App Instances](https://dev.wix.com/docs/build-apps/develop-your-app/access/app-instances/about-app-instances.md)