Example - Add to cart with personalization (mockData.json)
Use a text input to collect a personalization value and add it as a line item attribute. Includes a mockData.json example.
This example collects a short personalization string (for example, initials) and adds it as a line item attribute when adding to cart.
It also includes a mockData.json example so you can test useVariables() locally.
Code
import * as React from 'react';
import { Button, Text } from '@tapcart/mobile-components';
function isValid(value, maxLength) {
if (!value) return true;
if (value.length > maxLength) return false;
return /^[a-zA-Z0-9\s-]*$/.test(value);
}
export default function AddToCartPersonalizationExample({
pageState,
useActions,
useSearchParams,
useVariables,
blockConfig,
}) {
const { addToCart } = useActions();
const searchParams = useSearchParams();
const variables = useVariables();
const productId = searchParams.get('productId') || pageState?.searchParams?.productId;
const variantId = searchParams.get('variantId') || pageState?.searchParams?.variantId;
const maxLength = blockConfig?.maxLength ?? 12;
const [value, setValue] = React.useState('');
const [isAdding, setIsAdding] = React.useState(false);
const customerName = variables?.customer?.firstName || 'there';
const valid = isValid(value, maxLength);
const disabled = isAdding || !productId || !variantId || !valid;
const handleAdd = async () => {
if (disabled) return;
setIsAdding(true);
try {
await addToCart({
lines: [
{
productId,
variantId,
quantity: 1,
attributes: [
{
key: 'Personalization',
value: value.trim() || 'None',
},
],
},
],
});
} finally {
setIsAdding(false);
}
};
return (
<div style={{ padding: '16px' }}>
<Text type="body">Hi {customerName}. Add a note to this item:</Text>
<input
value={value}
onChange={(e) => setValue(e.target.value)}
placeholder="Example: JH"
style={{
marginTop: '12px',
width: '100%',
padding: '10px 12px',
border: '1px solid #ddd',
borderRadius: '8px',
}}
/>
{!valid ? (
<Text type="body" style={{ marginTop: '8px' }}>
Use letters, numbers, spaces, and dashes only (max {maxLength} characters).
</Text>
) : null}
<div style={{ marginTop: '12px' }}>
<Button onClick={handleAdd} disabled={disabled}>
{isAdding ? 'Adding…' : 'Add to cart'}
</Button>
</div>
</div>
);
}Manifest
[
{
"id": "maxLength",
"label": "Max characters",
"type": "range",
"defaultValue": 12,
"min": 1,
"max": 30,
"unit": "",
"step": 1
}
]mockData.json (optional)
Place mockData.json next to code.jsx while developing locally.
{
"customer": {
"id": "<UUID>",
"firstName": "Taylor"
}
}Notes
- This example assumes it’s placed on a product page (PDP) where
productIdandvariantIdare present in the page params.
Updated 24 days ago