Storage APIAPIs
APIs
The Storage API allows fetching, setting, updating, and clearing an extension's data from the POS local storage.
- An extension can store up to 100 entries.
- The maximum size for a key is ~1 KB, and for a value is ~1 MB.
- If a target (such as
pos.home.tile.render
) is disabled or removed, the extension data remains. - All stored extension data that has not been updated for a month is cleared automatically after that period.
Anchor to storageapiStorageApi
The data object provided to this extension target.
- Anchor to clearclear() => Promise<void>required
Clears the storage.
- Anchor to deletedelete<StorageTypes extends BaseStorageTypes = BaseStorageTypes, Keys extends keyof StorageTypes = keyof StorageTypes>(key: Keys) => Promise<boolean>required
Deletes a key from the storage.
- Anchor to entriesentries<StorageTypes extends BaseStorageTypes = BaseStorageTypes, Keys extends keyof StorageTypes = keyof StorageTypes>() => Promise<[Keys, StorageTypes[Keys]][]>required
Gets all the keys and values in the storage.
- <StorageTypes extends BaseStorageTypes = BaseStorageTypes, Keys extends keyof StorageTypes = keyof StorageTypes>(key: Keys) => Promise<StorageTypes[Keys]>required
Gets the value of a key in the storage.
- <StorageTypes extends BaseStorageTypes = BaseStorageTypes, Keys extends keyof StorageTypes = keyof StorageTypes>(key: Keys, value: StorageTypes[Keys]) => Promise<void>required
Sets the value of a key in the storage.
Storage
- clear
Clears the storage.
() => Promise<void>
- delete
Deletes a key from the storage.
<StorageTypes extends BaseStorageTypes = BaseStorageTypes, Keys extends keyof StorageTypes = keyof StorageTypes>(key: Keys) => Promise<boolean>
- entries
Gets all the keys and values in the storage.
<StorageTypes extends BaseStorageTypes = BaseStorageTypes, Keys extends keyof StorageTypes = keyof StorageTypes>() => Promise<[Keys, StorageTypes[Keys]][]>
- get
Gets the value of a key in the storage.
<StorageTypes extends BaseStorageTypes = BaseStorageTypes, Keys extends keyof StorageTypes = keyof StorageTypes>(key: Keys) => Promise<StorageTypes[Keys]>
- set
Sets the value of a key in the storage.
<StorageTypes extends BaseStorageTypes = BaseStorageTypes, Keys extends keyof StorageTypes = keyof StorageTypes>(key: Keys, value: StorageTypes[Keys]) => Promise<void>
export interface Storage<
BaseStorageTypes extends Record<string, any> = Record<string, unknown>,
> {
/**
* Sets the value of a key in the storage.
*
* @param key - The key to set the value for.
* @param value - The value to set for the key.
* Can be any primitive type supported by `JSON.stringify`.
* @throws StorageError when:
* the extension exceeds its allotted storage limit.
* the value exceeds its allotted storage limit.
* the key is not a string or exceeds its allotted size.
*/
set<
StorageTypes extends BaseStorageTypes = BaseStorageTypes,
Keys extends keyof StorageTypes = keyof StorageTypes,
>(
key: Keys,
value: StorageTypes[Keys],
): Promise<void>;
/**
* Gets the value of a key in the storage.
*
* @param key - The key to get the value for.
* @returns The value of the key.
* If no value for the key exists, the resolved value is undefined.
* @throws StorageError when the key is not a string or exceeds its allotted size.
*/
get<
StorageTypes extends BaseStorageTypes = BaseStorageTypes,
Keys extends keyof StorageTypes = keyof StorageTypes,
>(
key: Keys,
): Promise<StorageTypes[Keys] | undefined>;
/**
* Clears the storage.
*/
clear: () => Promise<void>;
/**
* Deletes a key from the storage.
*
* @param key - The key to delete.
*/
delete<
StorageTypes extends BaseStorageTypes = BaseStorageTypes,
Keys extends keyof StorageTypes = keyof StorageTypes,
>(
key: Keys,
): Promise<boolean>;
/**
* Gets all the keys and values in the storage.
*
* @returns An array containing all the keys and values in the storage.
*/
entries<
StorageTypes extends BaseStorageTypes = BaseStorageTypes,
Keys extends keyof StorageTypes = keyof StorageTypes,
>(): Promise<[Keys, StorageTypes[Keys]][]>;
}
Was this section helpful?
Anchor to examplesExamples
Examples of using the Storage API
Anchor to example-getting-a-single-value-from-storageGetting a single value from storage
Anchor to example-setting-a-single-value-in-storageSetting a single value in storage
Anchor to example-deleting-a-single-value-from-storageDeleting a single value from storage
Anchor to example-clear-all-entries-for-an-extension-from-storageClear all entries for an extension from storage
Anchor to example-retrieve-all-entries-for-an-extension-from-storageRetrieve all entries for an extension from storage
Was this section helpful?
Getting a single value from storage
import React from 'react';
import {
Tile,
reactExtension,
useApi,
} from '@shopify/ui-extensions-react/point-of-sale';
const TileComponent = () => {
const api = useApi<'pos.home.tile.render'>();
return (
<Tile
title="Storage app"
subtitle="Get example"
onPress={async () => {
const storedData = await api.storage.get('key');
api.toast.show(String(storedData ?? ''));
}}
enabled
/>
);
};
export default reactExtension('pos.home.tile.render', () => <TileComponent />);
examples
Getting a single value from storage
React
import React from 'react'; import { Tile, reactExtension, useApi, } from '@shopify/ui-extensions-react/point-of-sale'; const TileComponent = () => { const api = useApi<'pos.home.tile.render'>(); return ( <Tile title="Storage app" subtitle="Get example" onPress={async () => { const storedData = await api.storage.get('key'); api.toast.show(String(storedData ?? '')); }} enabled /> ); }; export default reactExtension('pos.home.tile.render', () => <TileComponent />);
TS
import {Tile, extension} from '@shopify/ui-extensions/point-of-sale'; export default extension('pos.home.tile.render', (root, api) => { const tile = root.createComponent(Tile, { title: 'Storage app', subtitle: 'Get example', enabled: true, onPress: async () => { const storedData = await api.storage.get('key'); api.toast.show(String(storedData ?? '')); }, }); root.append(tile); });
Setting a single value in storage
React
import React from 'react'; import type {Storage} from '@shopify/ui-extensions/point-of-sale'; import { Tile, reactExtension, useApi, } from '@shopify/ui-extensions-react/point-of-sale'; interface ExampleStorage { trackingId: string; someObject: Record<string, unknown>; attempts: number; } const TileComponent = () => { const api = useApi<'pos.home.tile.render'>(); const storage: Storage<ExampleStorage> = api.storage; return ( <Tile title="Storage app" subtitle="Set example" onPress={async () => { await Promise.all([ storage.set('trackingId', 'd6ead53c-b5f5-0b16-dabb-17081ff238c3'), storage.set('someObject', { boolean: true, numeric: 2, string: 'Hello world!', }), storage.set('attempts', 2), ]); }} enabled /> ); }; export default reactExtension('pos.home.tile.render', () => <TileComponent />);
TS
import {Tile, extension} from '@shopify/ui-extensions/point-of-sale'; import type {Storage} from '@shopify/ui-extensions/point-of-sale'; interface ExampleStorage { trackingId: string; someObject: Record<string, unknown>; attempts: number; } export default extension('pos.home.tile.render', (root, api) => { const storage: Storage<ExampleStorage> = api.storage; const tile = root.createComponent(Tile, { title: 'Storage app', subtitle: 'Set example', enabled: true, onPress: async () => { await Promise.all([ storage.set('trackingId', 'd6ead53c-b5f5-0b16-dabb-17081ff238c3'), storage.set('someObject', { boolean: true, numeric: 2, string: 'Hello world!', }), storage.set('attempts', 2), ]); }, }); root.append(tile); });
Deleting a single value from storage
React
import React from 'react'; import { Tile, reactExtension, useApi, } from '@shopify/ui-extensions-react/point-of-sale'; const TileComponent = () => { const api = useApi<'pos.home.tile.render'>(); return ( <Tile title="Storage app" subtitle="Delete example" onPress={async () => { await api.storage.set('key', 'A temporary value'); const storedData = await api.storage.get('key'); api.toast.show(`Current value: ${String(storedData)}`); setTimeout(async () => { api.storage.delete('key'); const storedData = (await api.storage.get('key')) ?? ''; api.toast.show(`Current value after deletion: ${String(storedData)}`); }, 2000); }} enabled /> ); }; export default reactExtension('pos.home.tile.render', () => <TileComponent />);
TS
import {Tile, extension} from '@shopify/ui-extensions/point-of-sale'; export default extension('pos.home.tile.render', (root, api) => { const tile = root.createComponent(Tile, { title: 'Storage app', subtitle: 'Delete example', enabled: true, onPress: async () => { await api.storage.set('key', 'A temporary value'); const storedData = await api.storage.get('key'); api.toast.show(`Current value: ${String(storedData)}`); setTimeout(async () => { api.storage.delete('key'); const storedData = (await api.storage.get('key')) ?? ''; api.toast.show(`Current value after deletion: ${String(storedData)}`); }, 2000); }, }); root.append(tile); });
Clear all entries for an extension from storage
React
import React, {useState, useEffect} from 'react'; import { Tile, reactExtension, useApi, } from '@shopify/ui-extensions-react/point-of-sale'; const TileComponent = () => { const api = useApi<'pos.home.tile.render'>(); const [itemCount, setItemCount] = useState(0); useEffect(() => { const initializeData = async () => { const count = 10; for (let i = 0; i < count; i++) { await api.storage.set(`key-${i}`, `value-${i}`); } setItemCount(count); }; initializeData(); }, [api.storage]); return ( <Tile title="Storage app" subtitle="Clear example" badgeValue={itemCount} onPress={async () => { await api.storage.clear(); api.toast.show('All data cleared'); setItemCount(0); }} enabled /> ); }; export default reactExtension('pos.home.tile.render', () => <TileComponent />);
TS
import {Tile, extension} from '@shopify/ui-extensions/point-of-sale'; export default extension('pos.home.tile.render', (root, api) => { let itemCount = 0; const tile = root.createComponent(Tile, { title: 'Storage app', subtitle: 'Clear example', badgeValue: itemCount, enabled: true, onPress: async () => { await api.storage.clear(); api.toast.show('All data cleared'); itemCount = 0; tile.updateProps({badgeValue: itemCount}); }, }); const initializeData = async () => { const count = 10; for (let i = 0; i < count; i++) { await api.storage.set(`key-${i}`, `value-${i}`); } itemCount = count; tile.updateProps({badgeValue: itemCount}); }; initializeData(); root.append(tile); });
Retrieve all entries for an extension from storage
React
import React from 'react'; import type {Storage} from '@shopify/ui-extensions/point-of-sale'; import { Tile, reactExtension, useApi, } from '@shopify/ui-extensions-react/point-of-sale'; interface ExampleStorage { attempts: number; darkMode: boolean; trackingId: string; } const TileComponent = () => { const api = useApi<'pos.home.tile.render'>(); const storage: Storage<ExampleStorage> = api.storage; return ( <Tile title="Storage app" subtitle="Entries example" onPress={async () => { await storage.set('attempts', 2); await storage.set('darkMode', true); await storage.set('trackingId', 'd6ead53c-b5f5-0b16-dabb-17081ff238c3'); const allEntries = await storage.entries(); const message = allEntries.length ? allEntries.map(([key, value]) => `${key}: ${value}`).join(', ') : 'Nothing stored'; api.toast.show(message); }} enabled /> ); }; export default reactExtension('pos.home.tile.render', () => <TileComponent />);
TS
import {Tile, extension} from '@shopify/ui-extensions/point-of-sale'; import type {Storage} from '@shopify/ui-extensions/point-of-sale'; interface ExampleStorage { attempts: number; darkMode: boolean; trackingId: string; } export default extension('pos.home.tile.render', (root, api) => { const storage: Storage<ExampleStorage> = api.storage; const tile = root.createComponent(Tile, { title: 'Storage app', subtitle: 'Entries example', enabled: true, onPress: async () => { await storage.set('attempts', 2); await storage.set('darkMode', true); await storage.set('trackingId', 'd6ead53c-b5f5-0b16-dabb-17081ff238c3'); const allEntries = await storage.entries(); const message = allEntries.length ? allEntries.map(([key, value]) => `${key}: ${value}`).join(', ') : 'Nothing stored'; api.toast.show(message); }, }); root.append(tile); });