Storage API
The Storage API provides persistent local storage for POS UI extensions, allowing you to store, retrieve, and manage extension data that persists across user sessions, device restarts, and extension target state changes. Data is stored locally on the POS device in an isolated namespace specific to your extension.
The API supports key-value storage with automatic JSON serialization, type safety through TypeScript interfaces, and built-in error handling for storage constraint violations.
Use cases
- Data caching: Cache product information and pricing data to reduce API calls.
- Preferences: Store user preferences like theme settings and workflow customizations.
- Contextual data: Pass data between tile and action (modal) targets during workflows.
- Session data: Maintain temporary session data that survives navigation and cart changes.
Supported targets
- pos.
cart. line-item-details. action. menu-item. render - pos.
cart. line-item-details. action. render - pos.
customer-details. action. menu-item. render - pos.
customer-details. action. render - pos.
customer-details. block. render - pos.
draft-order-details. action. menu-item. render - pos.
draft-order-details. action. render - pos.
draft-order-details. block. render - pos.
exchange. post. action. menu-item. render - pos.
exchange. post. action. render - pos.
exchange. post. block. render - pos.
home. modal. render - pos.
home. tile. render - pos.
order-details. action. menu-item. render - pos.
order-details. action. render - pos.
order-details. block. render - pos.
product-details. action. menu-item. render - pos.
product-details. action. render - pos.
product-details. block. render - pos.
purchase. post. action. menu-item. render - pos.
purchase. post. action. render - pos.
purchase. post. block. render - pos.
receipt-footer. block. render - pos.
receipt-header. block. render - pos.
register-details. action. menu-item. render - pos.
register-details. action. render - pos.
register-details. block. render - pos.
return. post. action. menu-item. render - pos.
return. post. action. render - pos.
return. post. block. render
Anchor to storageapiStorageApi
The object provides access to persistent local storage methods for your POS UI extension. Access these methods through shopify.storage to store, retrieve, and manage data that persists across sessions.
- Anchor to clearclearclear() => Promise<void>() => Promise<void>requiredrequired
Clears all data from storage, removing all key-value pairs.
- Anchor to deletedeletedelete<StorageTypes extends BaseStorageTypes = BaseStorageTypes, Keys extends keyof StorageTypes = keyof StorageTypes>(key: Keys) => Promise<boolean><StorageTypes extends BaseStorageTypes = BaseStorageTypes, Keys extends keyof StorageTypes = keyof StorageTypes>(key: Keys) => Promise<boolean>requiredrequired
Deletes a specific key from storage and returns
trueif the key existed,falseif it didn't exist. Returnsfalsefor non-existent keys rather than throwing an error. Commonly used for cleaning up temporary workflow data, removing expired cache entries, or handling user preference changes.- Anchor to entriesentriesentries<StorageTypes extends BaseStorageTypes = BaseStorageTypes, Keys extends keyof StorageTypes = keyof StorageTypes>() => Promise<[Keys, StorageTypes[Keys]][]><StorageTypes extends BaseStorageTypes = BaseStorageTypes, Keys extends keyof StorageTypes = keyof StorageTypes>() => Promise<[Keys, StorageTypes[Keys]][]>requiredrequired
Retrieves all stored key-value pairs as an array of tuples, preserving original data types. Returns all data at once which may impact memory usage with large datasets. Commonly used for debugging storage contents, implementing data export features, or performing bulk operations across stored data.
- Anchor to getgetget<StorageTypes extends BaseStorageTypes = BaseStorageTypes, Keys extends keyof StorageTypes = keyof StorageTypes>(key: Keys) => Promise<StorageTypes[Keys]><StorageTypes extends BaseStorageTypes = BaseStorageTypes, Keys extends keyof StorageTypes = keyof StorageTypes>(key: Keys) => Promise<StorageTypes[Keys]>requiredrequired
Retrieves the value associated with a key, returning
undefinedif the key doesn't exist. Always handle theundefinedcase by providing fallback values or conditional logic. Commonly used for loading user preferences, retrieving cached data, or accessing contextual information passed between extension targets.- Anchor to setsetset<StorageTypes extends BaseStorageTypes = BaseStorageTypes, Keys extends keyof StorageTypes = keyof StorageTypes>(key: Keys, value: StorageTypes[Keys]) => Promise<void><StorageTypes extends BaseStorageTypes = BaseStorageTypes, Keys extends keyof StorageTypes = keyof StorageTypes>(key: Keys, value: StorageTypes[Keys]) => Promise<void>requiredrequired
Stores a value under the specified key, overwriting any existing value. Values must be JSON-serializable and return
when storage limits are exceeded. Commonly used for storing user preferences, caching API responses, or passing contextual data from tiles to modals.
jsx
Examples
Clear all stored values
Description
Remove all stored data for your extension from persistent storage. This example demonstrates using `shopify.storage.clear()` to delete all key-value pairs stored by your extension. This is useful for reset functionality or clearing user preferences.
jsx
import {render} from 'preact'; import {useState, useEffect} from 'preact/hooks'; export default async () => { render(<Extension />, document.body); } function Extension() { const [itemCount, setItemCount] = useState(0); useEffect(() => { const initializeData = async () => { const count = 10; for (let i = 0; i < count; i++) { await shopify.storage.set(`key-${i}`, `value-${i}`); } setItemCount(count); }; initializeData(); }, []); return ( <s-tile heading="POS smart grid" subheading="preact Extension" itemCount={itemCount} onClick={async () => { await shopify.storage.clear(); shopify.toast.show('All data cleared'); setItemCount(0); }} /> ); }Remove a value from storage
Description
Delete a specific value from storage using its key. This example shows how to use `shopify.storage.delete()` to remove a stored item. This permanently clears the data associated with that key while leaving other stored values intact.
jsx
import {render} from 'preact'; export default async () => { render(<Extension />, document.body); } function Extension() { return ( <s-tile heading="POS smart grid" subheading="preact Extension" onClick={async () => { await shopify.storage.set('key', 'A temporary value'); const storedData = await shopify.storage.get('key'); shopify.toast.show(`Current value: ${String(storedData)}`); setTimeout(async () => { await shopify.storage.delete('key'); const storedData = (await shopify.storage.get('key')) ?? ''; shopify.toast.show(`Current value after deletion: ${String(storedData)}`); }, 2000); }} /> ); }Retrieve all stored entries
Description
Fetch all key-value pairs stored by your extension. This example shows how to use `shopify.storage.entries()` to retrieve an array of all stored items. This is useful for displaying saved data, performing bulk operations, or exporting stored information.
jsx
import {render} from 'preact'; export default async () => { render(<Extension />, document.body); } function Extension() { return ( <s-tile heading="POS smart grid" subheading="preact Extension" onClick={async () => { await shopify.storage.set('attempts', 2); await shopify.storage.set('darkMode', true); await shopify.storage.set('trackingId', 'd6ead53c-b5f5-0b16-dabb-17081ff238c3'); const allEntries = await shopify.storage.entries(); const message = allEntries.length ? allEntries.map(([key, value]) => `${key}: ${value}`).join(', ') : 'Nothing stored'; shopify.toast.show(message); }} /> ); }Retrieve a value from storage
Description
Read a stored value using its key from persistent storage. This example shows how to use `shopify.storage.get()` to retrieve a previously saved value. This returns the stored data with automatic JSON deserialization or undefined if the key does not exist.
jsx
import {render} from 'preact'; export default async () => { render(<Extension />, document.body); } function Extension() { return ( <s-tile heading="POS smart grid" subheading="preact Extension" onClick={async () => { const storedData = await shopify.storage.get('key'); shopify.toast.show(String(storedData ?? '')); }} /> ); }Save a value to storage
Description
Store a value in persistent storage using a key-value pair. This example demonstrates using `shopify.storage.set()` to save data that persists across user sessions, device restarts, and extension reloads. The value is automatically JSON serialized.
jsx
import {render} from 'preact'; export default async () => { render(<Extension />, document.body); } function Extension() { return ( <s-tile heading="POS smart grid" subheading="preact Extension" onClick={async () => { await Promise.all([ shopify.storage.set('trackingId', 'd6ead53c-b5f5-0b16-dabb-17081ff238c3'), shopify.storage.set('someObject', { boolean: true, numeric: 2, string: 'Hello world!', }), shopify.storage.set('attempts', 2), ]); shopify.toast.show('Data stored'); }} /> ); }
Anchor to best-practicesBest practices
- Design consistent key naming: Use hierarchical names like
settings.user.themeorcache.products.${id}to organize data. - Validate retrieved data: Check structure and types after
get()since data may be outdated. Provide defaults and handle missing properties. - Plan for data evolution: Include version fields and implement migration logic to handle schema updates between versions.
- Keep sensitive data out: Never store passwords, API keys, or sensitive information. Use Session API for secure backend communication.
Anchor to limitationsLimitations
- POS UI extensions can store up to a maximum of 100 entries.
- The maximum key size is ~1 KB and the maximum value size is ~1 MB.
- Data persists even when extension targets are disabled or removed.
- Stored extension data is automatically cleared after 30 days of inactivity. The inactivity timer is reset only by write operations (
set); read operations (get) do not affect the timer.