Additive, not a replacement. A widget layers your component onto a built-in page at a documented zone. Reach for it first whenever you just want to add something to an existing screen.
Add the button
Create the widget file
Drop a file under
src/widgets/. Export the component as the default and a config built with defineWidgetConfig. Target orders.detail.summary.after — your component renders in the order summary section footer and receives the loaded order as data.apps/vendor/src/widgets/order-copy-link.tsx
Understand the zone id
A zone id is
Multiple
<domain>.<view>.<slot>.<placement>. The last segment is the placement:| Placement | Effect |
|---|---|
before | Renders before the built-in content of the zone |
after | Renders after the built-in content |
before / after widgets on the same zone stack in registration order.Order detail zones
Zones mounted on the vendor order detail page:| Zone | Where it renders |
|---|---|
orders.detail.summary.before / .after | Inside the order summary section (around its footer) |
orders.detail.main.before / .after | Around the main column (summary, payment, fulfillment) |
orders.detail.side.before / .after | Around the sidebar (customer, activity) |
order as data. The full, valid set is typed as WidgetZoneId and generated from the panel’s own zone hosts — let your editor autocomplete zone: to see every option. A zone no page renders can’t be targeted and won’t type-check.
Verify
- Open an order — the “Copy link” button renders in the summary section footer.
- Click it — the link is copied and a toast appears.
- Change the zone to
orders.detail.side.beforeand reload — the button moves to the top of the sidebar. - Set
zone: "not.a.zone"—tsc(bun run lint) fails with a “not assignable toWidgetZoneId” error. - Delete the file — the button disappears; nothing else changed.
FAQ
What can I read from the order?
What can I read from the order?
The zone passes the loaded order as
data (HttpTypes.AdminOrder) — id, display id, totals, items, payment_collections, customer, and more. Build the link (or any UI) from it.Can a block ship this instead of the host app?
Can a block ship this instead of the host app?
Yes. Put the same file in a block’s
vendor_ui entry under src/widgets/; installing the block adds the button with no wiring.Can I render more than a button?
Can I render more than a button?
Next steps
Add a widget
The general widget model and the full list of zones.
Extend forms and tables
Add validated fields and columns with defineCustomFieldsConfig.