Sidekick Launch API
App Bridge isn't versioned with Polaris. App Bridge APIs and web components are identical in every App Home reference version.
App Bridge isn't versioned with Polaris. App Bridge APIs and web components are identical in every App Home reference version.
Use the Sidekick Launch API in embedded apps in the Shopify admin to start a Sidekick conversation for the merchant with a prompt your app provides. Call shopify.sidekick.launch() to open the Sidekick panel and send the prompt as the merchant's message.
You can also check whether Sidekick is available, open the panel without sending a prompt, and listen for panel visibility changes.
Anchor to Use casesUse cases
- Ask Sidekick from a report: Add an Ask Sidekick button next to a report so the merchant can ask Sidekick to summarize or explain the data shown in your app.
- Setup help: Start a conversation that helps the merchant with a step in your app's setup flow.
- In-app explanations: Help merchants understand campaign performance, churn, or other data shown in your app.
Anchor to MethodsMethods
| Method | Type | Description |
|---|---|---|
launch | LaunchFunction | Opens Sidekick and sends a message as the merchant's prompt. |
isEnabled | IsEnabledFunction | Checks whether Sidekick is available to the app on this store. |
isOpen | IsOpenFunction | Checks whether the Sidekick panel is open. |
open | OpenFunction | Opens the Sidekick panel without sending a prompt. |
There is no close method. Closing Sidekick is the merchant's decision.
Anchor to LaunchFunctionLaunchFunction
LaunchFunction| Parameter | Type | Description |
|---|---|---|
request | {message: string} | string | The prompt to send to Sidekick as the merchant's message. A string is shorthand for {message}. |
Returns: Promise<{id: string}>. Resolves with the new conversation ID. In the Shopify admin on the web, launch resolves after Sidekick finishes answering. In the Shopify mobile app, it resolves when Shopify hands the prompt to Sidekick, before Sidekick sends it. Don't treat a resolved launch as "Sidekick has answered", and don't time anything off it.
The message field is required, must be non-empty after trimming, and can be at most 5,500 characters. Leading and trailing whitespace is trimmed. launch ignores any other field, and doesn't treat it as an error. Hidden context or instructions, scenario, conversation IDs, and features aren't supported.
Anchor to IsEnabledFunctionIsEnabledFunction
IsEnabledFunctionChecks whether Sidekick is available to the app on this store.
Returns: Promise<boolean>
If the API isn't available, then shopify.sidekick methods reject. The shopify.sidekick object can still exist on the global, so feature-detect by calling isEnabled() and treating a rejection as unavailable:
Always check isEnabled() before you show a launch entry point or call any other method, and render the entry point only when it resolves true. Where the API isn't available, isEnabled() resolves false or rejects.
Anchor to IsOpenFunctionIsOpenFunction
IsOpenFunctionChecks whether the Sidekick panel is open.
Returns: Promise<boolean>
Anchor to OpenFunctionOpenFunction
OpenFunctionOpens the Sidekick panel without sending a prompt.
Returns: Promise<void>
In the Shopify mobile app, open and isOpen aren't available yet, and calling them rejects. Use launch to start a conversation.
Anchor to EventsEvents
App Bridge dispatches shopify:sidekick:visibilitychange on window when the Sidekick panel opens or closes. This event isn't dispatched in the Shopify mobile app.
| Property | Type | Description |
|---|---|---|
event.detail.visibilityState | 'visible' | 'hidden' | Whether the Sidekick panel is open or hidden. |
Anchor to Requirements and availabilityRequirements and availability
The Sidekick Launch API is available to apps embedded in the Shopify admin on the web and in the Shopify mobile app for iOS and Android, when they load App Bridge from https://cdn.shopify.com/shopifycloud/app-bridge.js. The API isn't available on every store or in every version of the Shopify mobile app. Where it isn't available, isEnabled() resolves false or rejects, so check it before you show a launch entry point.
The @shopify/app-bridge-types package doesn't include shopify.sidekick yet.
A launched conversation can use only your app's tools from its Sidekick app extensions, not other apps' tools. Prompts that ask to act across several apps or move data into another app are refused. If the merchant has turned your app off in Sidekick, then Shopify rejects launch.
Anchor to Prompt guidelinesPrompt guidelines
Before Shopify sends anything, Shopify screens the prompt. The check fails closed. If screening can't complete, then Shopify rejects the launch. The screening step adds latency, so launch is slower than typing into Sidekick. Shopify rate limits launches for each merchant, for each app, and across apps. Call launch in response to a merchant action, such as a button click. Don't call launch on page load or on a timer.
Allowed prompts include questions, reads, searches, summaries, explanations, drafts, content fixes on named resources, and changes inside your own app. Content fixes can include titles, descriptions, SEO fields, alt text, tags, metafields, and translations on specific products, collections, pages, or blog posts.
Shopify refuses prompts that:
- Are harmful or contain a URL or link.
- Try to steer Sidekick, such as asking it to ignore rules, prefer your app, hide things from the merchant, claim the merchant already approved something, or impersonate Shopify or Sidekick.
- Try to harvest store, customer, or financial data for the app.
- Ask for a risky store change, such as deleting or bulk-editing resources, moving money or changing prices, acting on orders, changing permissions, publishing themes or domains, changing settings, or sending marketing.
- Ask to act across several apps or move data into another app.
Sidekick shows the merchant that the conversation was started by your app. Sidekick never applies a store change from a launched prompt on its own. It proposes the change and only makes it after the merchant asks in their own message.
Anchor to ErrorsErrors
The Sidekick Launch API throws the following errors before Shopify sends anything. Each Error.message starts with sidekick.launch:.
| Error message | Cause |
|---|---|
sidekick.launch: message is required and must be a non-empty string. | No usable message. |
sidekick.launch: message must be at most 5500 characters. | The prompt is too long. |
sidekick.launch: the calling app could not be identified. | Shopify couldn't identify the calling app. |
sidekick.launch: the calling app is turned off in Sidekick. | The merchant turned your app off in Sidekick. |
sidekick.launch: whether the calling app is turned on in Sidekick could not be determined. | Shopify couldn't read the merchant's Sidekick app settings. Try again later. |
sidekick.launch: message was rejected. | The prompt didn't pass screening. The reason isn't disclosed. |
sidekick.launch: the prompt safety check could not be completed. | Screening errored or was rate limited. |
sidekick.launch: Sidekick is unavailable for maintenance. | Sidekick is in maintenance. |
sidekick.launch: this Shopify mobile app cannot open Sidekick for an app. | This version of the Shopify mobile app can't take a launch from your app. |
Errors without the sidekick.launch: prefix happen after screening, while Shopify creates or sends the conversation. Shopify might already have sent the prompt, so don't retry those errors automatically.
In the Shopify mobile app, launch rejects with Sidekick could not take the launch in the Shopify mobile app, and nothing was sent. when Sidekick refuses the prompt or can't take it, for example because your app's screen isn't the one in front. Shopify didn't send the prompt, so you can retry.
Versions of the Shopify mobile app released before Sidekick confirmed the handoff resolve launch without that confirmation, even if Sidekick then ignores the prompt. After launch resolves in the Shopify mobile app, Shopify doesn't report errors from sending the prompt to your app.
js
Examples
Launch a conversation
Description
Launch a Sidekick conversation from a merchant action. The button only appears when `isEnabled()` resolves `true`. Shopify sends the prompt as the merchant's message, and the Sidekick panel opens.
js
const button = document.getElementById('ask-sidekick'); const available = await shopify.sidekick?.isEnabled().catch(() => false); button.hidden = !available; if (available) { button.addEventListener('click', async () => { const conversation = await shopify.sidekick.launch({ message: 'Summarize my subscription churn for last month', }); console.log('Started Sidekick conversation', conversation.id); }); }Check availability
Description
Check whether Sidekick is available before showing your launch entry point. Treat a rejected `isEnabled()` call as unavailable.
js
const button = document.getElementById('ask-sidekick'); const available = await shopify.sidekick?.isEnabled().catch(() => false); button.hidden = !available; if (available) { button.addEventListener('click', () => { shopify.sidekick.launch( 'Which of my email campaigns performed best last month?', ); }); }Handle rejections
Description
Handle launch rejections after checking `isEnabled()`. Errors that start with `sidekick.launch:` happen before Shopify sends anything.
js
const button = document.getElementById('ask-sidekick'); const available = await shopify.sidekick?.isEnabled().catch(() => false); button.hidden = !available; if (available) { button.addEventListener('click', async () => { try { await shopify.sidekick.launch({ message: 'Summarize my subscription churn for last month', }); } catch (error) { const message = error instanceof Error ? error.message : String(error); if (message.startsWith('sidekick.launch:')) { shopify.toast.show(message, {isError: true}); return; } shopify.toast.show('Sidekick could not start the conversation.', { isError: true, }); } }); }Open Sidekick and listen for visibility changes
Description
Check `isEnabled()`, then open the Sidekick panel without sending a prompt and listen for `shopify:sidekick:visibilitychange` events.
js
const button = document.getElementById('open-sidekick'); const status = document.getElementById('sidekick-status'); const available = await shopify.sidekick?.isEnabled().catch(() => false); button.hidden = !available; if (available) { window.addEventListener('shopify:sidekick:visibilitychange', (event) => { status.textContent = event.detail.visibilityState === 'visible' ? 'Sidekick is open' : 'Sidekick is hidden'; }); button.addEventListener('click', async () => { await shopify.sidekick.open(); }); }Use Sidekick with React
Description
Use `useAppBridge` to render a button when Sidekick is available.
jsx
import {useEffect, useState} from 'react'; import {useAppBridge} from '@shopify/app-bridge-react'; export function AskSidekickButton() { const shopify = useAppBridge(); const [available, setAvailable] = useState(false); useEffect(() => { let mounted = true; shopify.sidekick?.isEnabled() .then((enabled) => { if (mounted) setAvailable(enabled); }) .catch(() => { if (mounted) setAvailable(false); }); return () => { mounted = false; }; }, [shopify]); if (!available) return null; return ( <button onClick={() => shopify.sidekick.launch( 'Which of my email campaigns performed best last month?', ) } > Ask Sidekick </button> ); }