Highlights
New Admin Layout Composer
The admin dashboard layout is now fully customizable through a reworked Layout Composer. You can rearrange the Topbar, Sidebar, Settings Sidebar and pages with drag and drop, and your arrangement is persisted in the database so it stays consistent across sessions and users.
This rework started as a community contribution from @leobenzol, who built the drag-and-drop Layout Composer and settings persistence and applied it across the shell. Thanks to their work, extending and reordering the dashboard layout is now a first-class part of the admin. A prime example of the kind of high-value features the community can drive in Medusa. Read more in the announcement.
Async Payment Methods Support
Medusa now supports asynchronous payment methods, where a payment is confirmed after the initial request through provider webhooks rather than synchronously. The support spans the Payment module, the Stripe provider, core workflows, the JS SDK, and the admin dashboard, so async methods are handled consistently across the checkout and payment lifecycle.
Tiered Pricing for Price List Prices
Price list prices now support quantity-based tiers directly in the admin. Click a price cell in the price list edit form to define multiple price tiers per variant and currency, making it straightforward to set up bulk discounts and other quantity-based pricing strategies across regions and currencies.
CleanShot.2026-07-01.at.13.57.02.mp4
Contextual Browser Tab Titles
The admin dashboard now sets a descriptive document title for each page, so multiple open tabs are easy to tell apart. List pages show the section name (for example "Products - Medusa") and detail pages surface the entity name (for example a product's title or an order's display id). Titles are resolved through a new seo resolver on each route's handle.
Custom admin pages in your own project can set their tab title the same way, by exporting a handle with an seo resolver from the route file. Return a static title, or derive one from the route's loader data via match.data:
// src/admin/routes/custom/page.tsx
import { defineRouteConfig } from "@medusajs/admin-sdk"
export const handle = {
seo: () => ({ title: "My Custom Page" }),
}
export const config = defineRouteConfig({
label: "My Custom Page",
})
const CustomPage = () => {
return <div>My custom page</div>
}
export default CustomPageFeatures
- feat: drag&drop LayoutComposer, settings db persistence by @leobenzol in #15721
- feat(payment,payment-stripe,core-flows,medusa,dashboard,js-sdk,utils,types): introduce async payment methods support by @NicolasGorga in #15085
- feat(dashboard): add dynamic document titles for browser tabs by @bqst in #14426
- feat(admin-shared,dashboard): apply new LayoutComposer approach across the admin dashboard by @NicolasGorga in #15861
- feat(admin-shared,dashboard): use layout composer in Topbar, Sidebar and settings Sidebar by @leobenzol in #15862
- feat(dashboard): add quantity-based pricing support for price lists by @laaibaQasim in #15258
Bugs
- fix(payment-stripe): handle async payment method check gracefully in webhook by @NicolasGorga in #15897
- fix(core-flows): keep customer account-holder link on a failed payment-session init by @Mezzle in #15618
- fix(utils): allow alias override in defineLink InputOptions to support linking the same module twice by @kowalski21 in #15701
- fix(order): make custom_display_id searchable by @Dev-Abdullah-H in #15622
- fix: Product option and product option values are not translatable by @weknowyourgame in #15881
- fix(core-flows,medusa): exclude gift cards from tax calc and add an option for custom gift card codes by @scherddel in #15419
- fix: move the remote joiner class to the modules SDK package by @sradevski in #15890
- fix(order): use isDefined check for unit_price in item-update action by @Dev-Abdullah-H in #15863
Chores
- chore: add package bugs metadata to published packages by @Floofy6 in #15683
- chore: remove unused test suites by @sradevski in #15888
- chore: remove legacy API tests that are no longer relevant by @sradevski in #15877
New Contributors
- @Mezzle made their first contribution in #15618
- @kowalski21 made their first contribution in #15701
- @laaibaQasim made their first contribution in #15258
- @weknowyourgame made their first contribution in #15881
- @Floofy6 made their first contribution in #15683
Full Changelog: v2.17.1...v2.17.2