Appearance
Migration plan: v2 → v3
Version 3 of @authentified/react-widget reshapes the AuthentifiedButton contract. The widget renders the same button in the same places — the change is in how you tell it what's being consigned.
This page documents every prop difference and gives you the exact JSX edits to upgrade.
At a glance
| Concern | v2 | v3 |
|---|---|---|
| Integration type | type="shopify" | "api" | "offline" | source="shopify" | "api" (default "shopify") |
| What's being consigned | scope="lineItem" | "order" (default "order") | scope="lineItem" | "order" | "offline" — required, no default |
| Offline / POS sales | type="offline" with variantId | scope="offline" with variantId and orderId (your POS / receipt reference) |
| ID prop types | string only | string | number |
customerId | Required string | Optional. Missing / null / empty string normalises to omitted in the request |
| Shopify line items | lineItemId (or variantId fallback for Storefront API) | lineItemId only — there's no longer a variantId fallback at scope="lineItem" |
| Removed exports | — | AuthentifiedLineItemButton, AuthentifiedButtonOrderType |
| New exports | — | AuthentifiedButtonSource |
The two-prop split
The single biggest change: type is gone, replaced by two orthogonal props.
source— how the shop integrates with Authentified ("shopify"or"api"). Defaults to"shopify".scope— what's being consigned ("lineItem","order", or"offline"). Required, no default.
In v2 these two concerns were conflated by type, which made it impossible to represent shops that sell both online (Shopify App) and offline (POS). In v3 a Shopify App shop selling offline is just source="shopify" scope="offline".
Step-by-step upgrade
Line-item buttons (Shopify App)
diff
- <AuthentifiedButton
- type="shopify"
- lineItemId={lineItem.id}
- productId={lineItem.product.id}
- orderId={order.id}
- customerId={customer.id}
- shopId={shop.id}
- />
+ <AuthentifiedButton
+ scope="lineItem"
+ source="shopify"
+ lineItemId={lineItem.id}
+ productId={lineItem.product.id}
+ orderId={order.id}
+ customerId={customer.id}
+ shopId={shop.id}
+ />1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Because source defaults to "shopify", you can drop it for Shopify shops:
tsx
<AuthentifiedButton
scope="lineItem"
lineItemId={lineItem.id}
productId={lineItem.product.id}
orderId={order.id}
shopId={shop.id}
/>1
2
3
4
5
6
7
2
3
4
5
6
7
WARNING
The v2 fallback that let you pass variantId instead of lineItemId (for the Shopify Storefront API, which doesn't expose line-item IDs) is gone. At scope="lineItem" you must supply lineItemId. If you only have variant IDs, see the order-scope upgrade path below — let the customer pick which items to consign on the Authentified flow.
Line-item buttons (REST API)
diff
- <AuthentifiedButton
- type="api"
- variantId={lineItem.variantId}
- productId={lineItem.product.id}
- orderId={order.id}
- customerId={customer.id}
- shopId={shop.id}
- />
+ <AuthentifiedButton
+ scope="lineItem"
+ source="api"
+ lineItemId={lineItem.id}
+ productId={lineItem.product.id}
+ orderId={order.id}
+ customerId={customer.id}
+ shopId={shop.id}
+ />1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
REST API integrations now use lineItemId like Shopify App integrations — the prop name no longer depends on source.
Order buttons
diff
- <AuthentifiedButton
- type="shopify"
- scope="order"
- orderId={order.id}
- customerId={customer.id}
- shopId={shop.id}
- />
+ <AuthentifiedButton
+ scope="order"
+ orderId={order.id}
+ customerId={customer.id}
+ shopId={shop.id}
+ />1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
scope was the default in v2 so it could be omitted; in v3 it's required. type is replaced by source (defaulted to "shopify", so omit it unless you're on REST API).
Offline buttons (POS / in-person sales)
diff
- <AuthentifiedButton
- type="offline"
- variantId={item.variantId}
- productId={item.productId}
- orderId={receipt.id}
- customerId={customer.id}
- shopId={shop.id}
- />
+ <AuthentifiedButton
+ scope="offline"
+ variantId={item.variantId}
+ productId={item.productId}
+ orderId={receipt.id}
+ customerId={customer.id}
+ shopId={shop.id}
+ />1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Offline is now a scope, not a type. orderId is your POS / receipt reference (receipt number, transaction ID — whatever you use to identify the offline sale).
customerId is now optional
v2 required customerId as a string. v3 accepts string, number, null, undefined, or "" — anything that isn't a populated string or number is normalised to "no customer" before the request is sent.
tsx
<AuthentifiedButton scope="lineItem" lineItemId="1" orderId="2" shopId="3" /> // no customerId — fine
<AuthentifiedButton scope="lineItem" lineItemId="1" orderId="2" shopId="3" customerId={null} /> // null — fine
<AuthentifiedButton scope="lineItem" lineItemId="1" orderId="2" shopId="3" customerId="" /> // empty string — fine1
2
3
2
3
If you were guarding the button render with customer ? <AuthentifiedButton ... /> : null in v2, you can drop the guard in v3 and let the widget handle the missing customer case.
IDs can be string | number
v2 forced string. v3 accepts either, so you can pass numeric IDs straight from your data layer:
tsx
<AuthentifiedButton
scope="lineItem"
lineItemId={lineItem.id} // number — fine
orderId={order.id} // number — fine
shopId={shop.id} // number — fine
customerId={customer.id} // number — fine
/>1
2
3
4
5
6
7
2
3
4
5
6
7
You no longer need String(id) / id.toString() calls before passing IDs to the widget.
TypeScript: discriminated union by scope
v3's AuthentifiedButtonProps is a discriminated union keyed on scope. The compiler narrows by the literal value, so:
scope="order"rejectslineItemId,variantId, andproductId.scope="lineItem"rejectsvariantId.scope="offline"rejectslineItemId.
This is stricter than v2, where you could pass any combination of props at compile time and rely on runtime behaviour. Run tsc after upgrading to catch any mismatched prop sets.
Removed exports
| Removed | Replacement |
|---|---|
AuthentifiedLineItemButton | AuthentifiedButton with scope="lineItem" |
AuthentifiedButtonOrderType | AuthentifiedButtonSource ("shopify" | "api") |
After you upgrade
- Update the import — no path change, just bump to
^3.0.0:shnpm i @authentified/react-widget@^31 - Replace every
type=withsource=(or drop it if you were using"shopify"). - Add
scope=to every<AuthentifiedButton>— there's no default any more. - Convert any
type="offline"instances toscope="offline". - Run
tscto catch any prop combinations the new discriminated union rejects. - Drop manual
String(id)calls on ID props if you have them.