Skip to main content

Overriding the Address Page

You can completely customize the address management experience in your app by overriding the default Address Page. This is done by creating a custom block and mapping it to the Address Page schema.

Pattern Overview

  1. Page Schema: Defines the page structure and includes a block identifier (e.g., shopify/address-list).
  2. Blocks Schema: Connects that block identifier to your custom React component.
  3. Hooks: Use useAddressList and useAddressActions within your component to manage data.

Essential Hooks

1. useAddressList

Fetches all shipping addresses for the currently logged-in user.

  • Returns:
    • addressList: Array of address objects.
    • defaultAddressId: The ID of the primary address.
    • isFetching: Boolean loading state.
    • refetch: Function to reload the data.

2. useAddressActions

Provides methods to modify addresses on Shopify.

  • Returns:
    • deleteAddress(id): Removes an address.
    • setDefaultAddress(id): Sets an address as the primary one.

Implementation Guide

1. Define the Page Schema (page.schema.js)

const AddressPageSchema = {
type: 'normal',
title: 'My Addresses',
blocks: [
{
name: 'custom/address-manager',
attributes: {},
},
],
};

export default AddressPageSchema;

2. Map the Block (blocks.schema.js)

import AddressManager from './components/AddressManager';

const AddressBlocks = [
{
name: 'custom/address-manager',
View: AddressManager,
},
];

export default AddressBlocks;

3. Build the Custom Component (AddressManager.js)

import React from 'react';
import { useAddressList, useAddressActions } from '@appmaker-xyz/shopify';
import { Layout, ThemeText, Button } from '@appmaker-xyz/ui';

const AddressManager = ({ onAction }) => {
const { addressList, isFetching, refetch, defaultAddressId } = useAddressList();
const { deleteAddress, setDefaultAddress } = useAddressActions();

if (isFetching && !addressList) return <ActivityIndicator />;

return (
<Layout>
<Button
title="Add New Address"
onPress={() => onAction({ action: 'OPEN_SHIPPING_ADDRESS_CREATE' })}
/>
{addressList.map(item => (
<Layout key={item.id}>
<ThemeText>{item.address1}</ThemeText>
<Button
title="Set Default"
onPress={() => setDefaultAddress(item.id).then(refetch)}
/>
</Layout>
))}
</Layout>
);
};

Theme Integration

For a clean and modular setup, follow this registration pattern by collecting all schemas and blocks in dedicated entry files.

1. Collect Your Page Schema (src/pages/index.js)

Add your customized page schema to the pages object:

import AddressPageSchema from './AddressPage/page.schema';

export const pages = {
// ... other pages
AddressListCustomerCart: AddressPageSchema,
};

2. Collect Your Block Components (src/blocks.js)

Export all your custom block definitions in a single array:

import AddressBlocks from './pages/AddressPage/blocks.schema';

export const blocks = [
// ... other blocks
...AddressBlocks,
];

3. Register the Theme (src/index.js)

Finally, import the collected pages and blocks into your theme's main entry point:

import { registerTheme } from '@appmaker-xyz/core';
import { pages } from './pages';
import { blocks } from './blocks';

const MyTheme = {
id: 'my-custom-theme',
pages,
blocks,
activate: (params) => {
// Theme activation logic
},
};

registerTheme(MyTheme);