Cart Formcomponent
component
Creates a form for managing cart operations. Use to accept form inputs of known type.
Anchor to propsProps
Anchor to CartActionInputProps
CartActionInputProps
| | | | | | | | | | | | | | |
Anchor to CartFormCommonProps
CartFormCommonProps
Anchor to children
children
ReactNode | ((fetcher: FetcherWithComponents<any>) => ReactNode)
required
Children nodes of CartForm. Children can be a render prop that receives the fetcher.
Anchor to fetcherKey
fetcherKey
string
Optional key to use for the fetcher.
Anchor to route
route
string
The route to submit the form to. Defaults to the current route.
Was this section helpful?
Example
import {data} from 'react-router';
import {CartForm} from '@shopify/hydrogen';
import invariant from 'tiny-invariant';
export default function Cart() {
return (
<CartForm
action={CartForm.ACTIONS.LinesUpdate}
inputs={{
lines: [
{
id: 'gid://shopify/CartLine/123456789',
quantity: 3,
},
],
other: 'data',
}}
>
<button>Quantity up</button>
</CartForm>
);
}
export async function action({request, context}) {
const {cart} = context;
const formData = await request.formData();
const {action, inputs} = CartForm.getFormInput(formData);
let status = 200;
let result;
if (action === CartForm.ACTIONS.LinesUpdate) {
result = await cart.updateLines(inputs.lines);
} else {
invariant(false, `${action} cart action is not defined`);
}
const headers = cart.setCartId(result.cart.id);
return data(result, {status, headers});
}
Anchor to examplesExamples
Examples of various ways to use the component.
Anchor to example-exampleExample
Use HTML input tags with CartForm to accept form inputs.
Was this section helpful?
Example
import {data} from 'react-router';
import {CartForm} from '@shopify/hydrogen';
import invariant from 'tiny-invariant';
export default function Note() {
return (
<CartForm action={CartForm.ACTIONS.NoteUpdate}>
<input type="text" name="note" />
<button>Update Note</button>
</CartForm>
);
}
export async function action({request, context}) {
const cart = context.cart;
const formData = await request.formData();
const {action, inputs} = CartForm.getFormInput(formData);
let status = 200;
let result;
if (action === CartForm.ACTIONS.NoteUpdate) {
result = await cart.updateNote(inputs.note);
} else {
invariant(false, `${action} cart action is not defined`);
}
const headers = cart.setCartId(result.cart.id);
return data(result, {status, headers});
}
Anchor to example-custom-actionsCustom actions
Anchor to example-exampleExample
Create custom actions to accept form inputs of unknown type. Just prepend Custom
in front of your custom action name.
Was this section helpful?
Example
import {data} from 'react-router';
import {CartForm} from '@shopify/hydrogen';
import invariant from 'tiny-invariant';
export default function Cart() {
return (
<CartForm
action="CustomEditInPlace"
inputs={{
addLines: [
{
merchandiseId: 'gid://shopify/Product/123456789',
quantity: 1,
},
],
removeLines: ['gid://shopify/CartLine/123456789'],
}}
>
<button>Green color swatch</button>
</CartForm>
);
}
export async function action({request, context}) {
const {cart} = context;
const formData = await request.formData();
const {action, inputs} = CartForm.getFormInput(formData);
let status = 200;
let result;
if (action === 'CustomEditInPlace') {
result = await cart.addLines(inputs.addLines);
result = await cart.removeLines(inputs.removeLines);
} else {
invariant(false, `${action} cart action is not defined`);
}
const headers = cart.setCartId(result.cart.id);
return data(result, {status, headers});
}
Anchor to example-cartform-with-fetcherCartForm with fetcher
Anchor to example-exampleExample
Use with a fetcher to manually submit the form. An example usage is to submit the form on changes to the state of a checkbox.
When using fetcher to submit, make sure to have a data key and its data should be a JSON stringify object.
Was this section helpful?
Example
import {useFetcher} from 'react-router';
import {data} from 'react-router';
import {CartForm} from '@shopify/hydrogen';
import invariant from 'tiny-invariant';
export function ThisIsGift({metafield}) {
const fetcher = useFetcher();
const buildFormInput = (event) => ({
action: CartForm.ACTIONS.MetafieldsSet,
inputs: {
metafields: [
{
key: 'custom.gift',
type: 'boolean',
value: event.target.checked.toString(),
},
],
},
});
return (
<div>
<input
checked={metafield?.value === 'true'}
type="checkbox"
id="isGift"
onChange={(event) => {
fetcher.submit(
{
[CartForm.INPUT_NAME]: JSON.stringify(buildFormInput(event)),
},
{method: 'POST', action: '/cart'},
);
}}
/>
<label htmlFor="isGift">This is a gift</label>
</div>
);
}
export async function action({request, context}) {
const {cart} = context;
const formData = await request.formData();
const {action, inputs} = CartForm.getFormInput(formData);
let status = 200;
let result;
if (action === CartForm.ACTIONS.MetafieldsSet) {
result = await cart.setMetafields(inputs.metafields);
} else {
invariant(false, `${action} cart action is not defined`);
}
const headers = cart.setCartId(result.cart.id);
return data(result, {status, headers});
}