@djust-b2b/djust-shipping-nuxt
v1.0.1
Published
Djust Shipping Nuxt module
Readme
@djust-b2b/djust-shipping-nuxt
Plug-and-play Nuxt 3/4 module for the DJUST Front Office Client (FOC) shipping step: real delivery-mode selection (aligned on the backend rate matrix) and shipping fees display, on top of the existing checkout APIs.
It ships a framework-agnostic core (src/runtime/core, pure TypeScript, no
Vue/Nuxt imports) so the business logic can be reused on Nuxt 2 or fully custom frontends.
The UI already supports offered shipping when the backend returns
price: 0with a non-zerobaseShippingPrice(strikethrough + “Free”). If you want a dedicated “franco progress” bar (threshold/remaining), use thecomputeFrancohelper from/coreand build your own UI — it is not wired into V1 components.
Requirements
The host app must expose a request-scoped SDK on the Nitro event context:
// server/plugins/djust-sdk.ts (host)
event.context.djustSDK = () => useDjustSDK(event) // returns a DjustScopedClientThe module BFF calls sdk.services.logisticOrder.* and
sdk.services.commercialOrder.updateShippingAddress with sdk.context. These
service methods require @djust-b2b/djust-front-sdk v3+; if your project is still
pinned to SDK v2, keep the module disabled until upgraded, or use core only with your own API layer.
Install
npm i @djust-b2b/djust-shipping-nuxt
# or, during local development against the starter:
# add "@djust-b2b/djust-shipping-nuxt": "file:../djust-shipping-module-nuxt"// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@djust-b2b/djust-shipping-nuxt'],
})Activation flag
The module always registers its imports, components and BFF routes when installed.
The runtime feature flag that gates the checkout UI is
runtimeConfig.public.djustShipping.enabled. An explicit value set by the app
(or hydrated from Studio, like djust-pay) takes precedence over the module
default:
// nuxt.config.ts — off by default, toggle per tenant/Studio
runtimeConfig: {
public: {
djustShipping: { enabled: false },
},
},Local dev linking (against a consumer)
For live iteration, consume it as a portal: dependency (symlink) so a module
rebuild is picked up after a consumer dev-server restart:
// consumer package.json
"@djust-b2b/djust-shipping-nuxt": "portal:../djust-shipping-module-nuxt"# in djust-shipping-module-nuxt
yarn install
yarn prepack # builds dist/ (re-run after each change)
# in the consumer
yarn install # creates the portal symlink
npx nuxi prepare # regenerates auto-import/component types
# then restart the dev serverWhat it provides
The module is layered so a theme picks the level it needs:
- Composables (auto-imported):
useDjustShipping()— low level: per-logistic-order option fetching, selection state, auto-select,isResolvedguard.useDjustShippingCheckout({ getOrder, onRefetch })— high-level checkout orchestration:applyAddress(shippingAddressId)(address at commercial + logistic levels, then resolves the eligible modes),isResolved,hasUnavailable,orderLogistics,refresh(),applying.
- Components (auto-imported, global):
<DjShippingSelector :order-id>— delivery-mode selector for one logistic order.<DjShippingFees :amount>— shipping fees line.<DjShippingFrancoBar>— franco progress bar per logistic with CSS variable theming.<DjShippingModesList :order>— loopsorder.orderLogistics, renders per-logistic blocks with franco bar, product lines, and mode selector. Slotstitle/blocked/no-options/products/loading. Fully customizable via props and CSS variables. Emitschange.
- BFF routes:
GET /api/shipping/logistic-orders/:orderId/optionsPUT /api/shipping/logistic-orders/:orderId/typePUT /api/shipping/commercial-orders/:orderId/addressPUT /api/shipping/logistic-orders/:orderId/address
Integration (starter-like Nuxt 4 themes)
For themes derived from the partners starter, integration is ~5 lines per shipping screen.
See the Docus guide (yarn docs:dev → /en/getting-started/integration or /fr/getting-started/integration) and the djust-shipping-integrate skill.
- Add the dependency and register the module (
nuxt.config.tsmodules). - Add the flag:
runtimeConfig.public.djustShipping = { enabled: '' }(env-driven, off by default) — mirrors thedjustPaypattern. - In the shipping screen, on address selection call the module orchestration
instead of the hardcoded
shippingType: 'STD':
const { getUserCurrency } = useUser()
const { getCart } = useCheckout()
const config = useRuntimeConfig()
const shippingModuleEnabled = computed(() => !!config.public.djustShipping?.enabled)
const addressApplied = ref(false)
const order = computed(() => useCheckoutStore().currentCart)
const currency = computed(() => getUserCurrency())
const orderLogistics = computed(() => order.value?.orderLogistics ?? [])
const refreshOrder = async () => {
const ref_ = order.value?.reference
if (ref_) await getCart(ref_)
}
const { applyAddress, isResolved: shippingResolved } = useDjustShippingCheckout({
getOrder: () => order.value,
onRefetch: refreshOrder,
})
// on address selection (module path):
addressApplied.value = await applyAddress(address.externalId)- Render the list (module-owned UI + i18n), gated by the flag:
<DjShippingModesList
v-if="shippingModuleEnabled && addressApplied && orderLogistics.length"
:order="order"
:currency="currency"
@change="refreshOrder"
/>- Gate the Continue/Pay button on
shippingResolvedwhen the flag is on, and keep the existing'STD'flow in theelsebranch.
All user-facing strings for the group/list live in the module locales
(djustShipping.group.*, djustShipping.modes.*) — do not re-add them in the
theme.
Core (agnostic)
mapShippingOptions(raw)— normalize the shipping-information response (array or SDK wrapper) intoShippingOption[].selectDefaultShippingType(options, current?)— keep valid current, else auto-select when single, elsenull.isShippingResolved(states)— all logistic orders have a selected type.computeFranco(source, { eligibleAmount })— optional helper to normalize a franco threshold object (defensive field-name mapping) and derive the remaining amount; returnsnullwhen no franco applies. Not wired into V1 components.
The core is published under /core for Nuxt 2 or fully custom frontends (no Nuxt module — use your own API layer):
import { mapShippingOptions, selectDefaultShippingType, isShippingResolved }
from '@djust-b2b/djust-shipping-nuxt/core'Development
yarn install
yarn dev # runs the playground
yarn test # unit tests (core)
yarn lintDocumentation (Docus)
Site Docus bilingue FR / EN dans docs/.
yarn docs:dev # http://localhost:3000/en or /fr
yarn docs:buildPages clés :
- Integration guide (EN)
- Guide d'intégration (FR)
- AI Integration / MCP (EN) — endpoint
/mcp - Intégration IA / MCP (FR)
- Skills (EN) —
djust-shipping-integrate
