Skip to main content
Back to changelog

App intents on admin.app.intent.link now open as a full-page navigation

When Sidekick invokes an app intent declared on the admin.app.intent.link extension target, the Shopify admin now navigates the merchant to your extension's url as a full page, matching how Shopify's own admin intents behave. Previously, the same intent always opened in an overlay on top of the page the merchant was already on. This is live for all shops, isn't gated by API version, and doesn't require any changes to your extension's configuration, intent schema, or tools. Extensions that use the admin.app.intent.render target aren't affected.

What changed

App intents support different presentations. Until now, every app intent appeared as an intent modal, an overlay on top of the merchant's current page that kept them in the Sidekick flow. admin.app.intent.link intents now use a full-page navigation instead, which brings app intents in line with how admin intents, the intents that launch Shopify-native editors, are already presented. It also matches the documented behavior of the target, which navigates the merchant to a URL in your app for actions that work best on a page you already render. For implementation details, see Use extensions to surface app actions.

There's one case where the overlay is still used: if the merchant has unsaved changes on their current page, the intent opens in a modal instead of navigating away, so their in-progress work isn't lost. Your extension doesn't need to handle these cases differently — the same route, payload, and tools are used in both presentations.

The contract between Sidekick and your app is unchanged. Your route still reads the invocation payload from shopify.intents.request.value, a live signal that's null when your app isn't running inside an intent workflow and updates whenever an intent is invoked. You still register tool handlers with shopify.tools.register from the route the url opens, and you still resolve the intent with shopify.intents.response.ok(), shopify.intents.response.error(), or shopify.intents.response.closed().


Note

Extensions that target admin.app.intent.render currently render inline as an overlay, so a UI extension app action behaves the same as before.


If you noticed this change before this post and reported it as a regression, the new behavior is expected. The type, target, and url on your extension continue to work as declared.

Who's affected

This applies to apps with an admin_link extension whose targeting includes admin.app.intent.link. It applies on every API version and every store, and there's no feature flag, scope, or setting to opt in or out.

These aren't affected:

  • Extensions targeting admin.app.intent.render.
  • Admin intents your app invokes with intents.invoke() to launch Shopify-native editors. Those are a separate system and their presentation hasn't changed.
  • Apps that don't declare app intents.

If your app declares both targets, only the admin.app.intent.link intents change.

Why this matters

Merchants now land on the real page in your app, at the URL you declared, with your own layout and navigation instead of a constrained overlay. For the actions admin.app.intent.link is designed for, the merchant now works directly on the page your app already renders.

What to do

No action is required to keep your extension working. The declaration this change affects is the admin.app.intent.link target in your shopify.extension.toml:

[[extensions.targeting]]
target = "admin.app.intent.link"
url = "/app/campaigns/{id}/edit"
tools = "./tools.json"
instructions = "./instructions.md"

This example shows a typical admin.app.intent.link configuration: the target, the route the admin opens, and the files that define tools and instructions. You don't need to change this structure for the new behavior.

If your app has no extension with that target, nothing changes for you. If it does, verify that the route behind url works as a standalone page:

  1. Confirm the route renders correctly at full width. Layout that assumed a narrow overlay may need adjusting. The route should also still render correctly in a modal, since that's the presentation merchants with unsaved changes will see.
  2. Confirm the route reads the invocation payload from shopify.intents.request.value. Because it's a live signal, you can also subscribe to it to react when the request changes.
  3. Confirm the route calls shopify.tools.register when it mounts, so Sidekick can invoke your tools while the merchant is on the page.
  4. Confirm you resolve the intent when the merchant finishes, fails, or cancels.
  5. Test in a development store with shopify app dev, then ask Sidekick to perform the action.

You'll know the update worked when the admin navigates to your declared url with your schema's values substituted into the path rather than a literal {id}, your tools respond while the page is open, and Sidekick reports the result after you resolve the intent. To see the modal fallback, start editing a form in the admin and invoke the action before saving.

Related docs

Was this page helpful?